summaryrefslogtreecommitdiffstats
path: root/examples/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'examples/scripts')
-rw-r--r--examples/scripts/debugging/linux/backtrace41
-rwxr-xr-xexamples/scripts/debugging/smbXsrvdump87
-rw-r--r--examples/scripts/debugging/solaris/README28
-rw-r--r--examples/scripts/debugging/solaris/solaris-oops.sh57
-rw-r--r--examples/scripts/eventlog/parselog.pl32
-rw-r--r--examples/scripts/idmap/README168
-rwxr-xr-xexamples/scripts/idmap/idmap_nis.sh120
-rw-r--r--examples/scripts/mount/mount.smbfs115
-rwxr-xr-xexamples/scripts/nmb/findsmb160
-rw-r--r--examples/scripts/nmb/findsmb.1.xml145
-rwxr-xr-xexamples/scripts/printing/cups/smbaddprinter.pl39
-rwxr-xr-xexamples/scripts/printing/cups/smbdelprinter.pl25
-rwxr-xr-xexamples/scripts/users_and_groups/adduserstogroups.pl166
-rwxr-xr-xexamples/scripts/users_and_groups/createdomobj.pl159
-rwxr-xr-xexamples/scripts/vfs/media_harmony/trigger_avid_update.py106
-rw-r--r--examples/scripts/vfs/virusfilter/virusfilter-notify.ksh284
-rw-r--r--examples/scripts/wins_hook/README8
-rw-r--r--examples/scripts/wins_hook/dns_update92
18 files changed, 1832 insertions, 0 deletions
diff --git a/examples/scripts/debugging/linux/backtrace b/examples/scripts/debugging/linux/backtrace
new file mode 100644
index 0000000..7d14ff8
--- /dev/null
+++ b/examples/scripts/debugging/linux/backtrace
@@ -0,0 +1,41 @@
+#! /bin/sh
+#
+# Author: Andrew Tridgell <tridge at samba dot org>
+
+# we want everything on stderr, so the program is not disturbed
+exec 1>&2
+
+BASENAME=$(basename $0)
+
+test -z ${GDB_BIN} && GDB_BIN=$(type -p gdb)
+if [ -z ${GDB_BIN} ]; then
+ echo "ERROR: ${BASENAME} needs an installed gdb. "
+ exit 1
+fi
+
+if [ -z $1 ]; then
+ echo "ERROR: ${BASENAME} needs a PID. "
+ exit 1
+fi
+PID=$1
+
+# use /dev/shm as default temp directory
+test -d /dev/shm &&
+ TMP_BASE_DIR=/dev/shm ||
+ TMP_BASE_DIR=/var/tmp
+TMPFILE=$(mktemp -p ${TMP_BASE_DIR} backtrace.XXXXXX)
+if [ $? -ne 0 ]; then
+ echo "ERROR: ${basename} can't create temp file in ${TMP_BASE_DIR}. "
+ exit 1
+fi
+
+cat <<EOF >"${TMPFILE}"
+set height 0
+up 8
+bt full
+quit
+EOF
+
+${GDB_BIN} -x "${TMPFILE}" "/proc/${PID}/exe" "${PID}"
+
+/bin/rm -f "${TMPFILE}"
diff --git a/examples/scripts/debugging/smbXsrvdump b/examples/scripts/debugging/smbXsrvdump
new file mode 100755
index 0000000..f5c3091
--- /dev/null
+++ b/examples/scripts/debugging/smbXsrvdump
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+
+import sys
+
+sys.path.insert(0, "bin/python")
+
+import os
+import argparse
+import struct
+
+from samba.ndr import ndr_unpack, ndr_print
+from samba.dcerpc import smbXsrv
+from samba.dcerpc import server_id
+import tdb
+
+def print_watchers(num_watched, blob):
+ for i in range(0,num_watched):
+ id = ndr_unpack(server_id.server_id, blob[:24])
+ print(ndr_print(id))
+ blob = blob[24:]
+
+def print_record(data, ndr_type, watched, ctdb):
+ blob = data
+
+ if ctdb:
+ (rsn, dmaster, reserved1, flags) = struct.unpack('QIII', bytes(blob[:20]))
+ blob = blob[24:]
+ print(" ctdb record header: rsn=%lu, dmaster=%u, reserved1=0x%x, flags=0x%x len=%u" %
+ (rsn, dmaster, reserved1, flags, len(blob)))
+ if len(blob) == 0:
+ return
+
+ if watched:
+ (num_watched, ) = struct.unpack('I', bytes(blob[:4]))
+ blob = blob[4:]
+
+ deleted_bit = 1<<31
+ deleted = num_watched & deleted_bit
+
+ num_watched = num_watched & ~deleted_bit
+ if num_watched > 0:
+ if deleted:
+ deleted_str = "yes"
+ else:
+ deleted_str = "no"
+ print(" num_watched: %d, deleted: %s" % (num_watched, deleted_str))
+ print_watchers(num_watched, blob)
+ blob = blob[num_watched*4:]
+
+ unpacked = ndr_unpack(ndr_type, blob, allow_remaining=True)
+ print(ndr_print(unpacked))
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+ parser.add_argument('path', help='Path to the TDB file')
+ parser.add_argument('-c', '--ctdb',
+ default=False,
+ action="store_true",
+ help='The TDB database is from a ctdb cluster')
+ args = parser.parse_args()
+
+ watched = False
+ if 'smbXsrv_session' in args.path:
+ ndr_type = smbXsrv.session_globalB
+ watched = True
+ elif 'smbXsrv_open' in args.path:
+ ndr_type = smbXsrv.open_globalB
+ elif 'smbXsrv_client' in args.path:
+ ndr_type = smbXsrv.client_globalB
+ watched = True
+ elif 'smbXsrv_tcon' in args.path:
+ ndr_type = smbXsrv.tcon_globalB
+ elif 'smbXsrv_version' in args.path:
+ ndr_type = smbXsrv.version_globalB
+ else:
+ raise Exception("Failed to guess NDR type")
+
+ tdb = tdb.Tdb(args.path, 0, tdb.INCOMPATIBLE_HASH, os.O_RDONLY)
+
+ i = 1
+ for k in tdb.keys():
+ data = tdb.get(k)
+ print("Record: %d" % i)
+ print_record(data, ndr_type, watched, args.ctdb)
+ i = i + 1
+
+ tdb.close()
diff --git a/examples/scripts/debugging/solaris/README b/examples/scripts/debugging/solaris/README
new file mode 100644
index 0000000..9e33680
--- /dev/null
+++ b/examples/scripts/debugging/solaris/README
@@ -0,0 +1,28 @@
+Last update: John H Terpstra - June 27, 2005
+
+Subject: This directory will contain debugging tools and tips.
+
+Notes: Identification and confirmation of some bugs can be difficult.
+ When such bugs are encountered it is necessary to provide as
+ sufficient detailed debugging information to assist the developer
+ both by providing incontrivertable proof of the problem, but also
+ precise information regarding the values of variables being processed
+ at the time the problem strikes.
+
+ This directory is the ideal place to locate useful hints, tips and
+ methods that will help Samba users to provide the information that
+ developers need.
+
+============================ Solaris Method A ==============================
+File: solaris-oops.sh
+Contributor: David Collier-Brown
+Date: June 27, 2005
+Method and Use:
+To the global stanza of smb.conf add:
+ panic action = /usr/local/bin/solaris-oops.sh %d
+
+When the panic action is initiated a voluntary core dump file will be placed
+in /var/tmp. Use this method with "log level = 10" and an smbd binary that
+has been built with the '-g' option.
+============================================================================
+
diff --git a/examples/scripts/debugging/solaris/solaris-oops.sh b/examples/scripts/debugging/solaris/solaris-oops.sh
new file mode 100644
index 0000000..2d8587d
--- /dev/null
+++ b/examples/scripts/debugging/solaris/solaris-oops.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# solaris_panic_action -- capture supporting information after a failure
+#
+ProgName=$(basename $0)
+LOGDIR=/usr/local/samba/var
+
+main()
+{
+ pid=$1
+
+ if [ $# -lt 1 ]; then
+ say "$ProgName error: you must supply a pid"
+ say "Usage: $0 pid"
+ exit 1
+ fi
+ cat >>$LOGDIR/log.solaris_panic_action <<!
+
+$(date)
+State information and vountary core dump for process $pid
+
+Related processes were:
+$(/usr/bin/ptree $pid)
+
+Stack(s) were:
+$(/usr/bin/pstack $pid)
+
+Flags were:
+$(/usr/bin/pflags $pid)
+
+Credentials were:
+$(/usr/bin/pcred $pid)
+
+Libraries used were:
+$(/usr/bin/pldd $pid)
+
+Signal-handler settings were:
+$(/usr/bin/psig $pid)
+
+Files and devices in use were:
+$(/usr/bin/pfiles $pid)
+
+Directory in use was:
+$(/usr/bin/pwdx $pid)
+
+
+A voluntary core dump was placed in /var/tmp/samba_solaris_panic_action_gcore.$pid
+$(gcore -o /var/tmp/samba_solaris_panic_action_gcore $pid)
+!
+}
+
+say()
+{
+ echo "$@" 1>&2
+}
+
+main "$@"
diff --git a/examples/scripts/eventlog/parselog.pl b/examples/scripts/eventlog/parselog.pl
new file mode 100644
index 0000000..a2f9a27
--- /dev/null
+++ b/examples/scripts/eventlog/parselog.pl
@@ -0,0 +1,32 @@
+#!/usr/bin/perl
+######################################################################
+##
+## Simple parselog script for Samba
+##
+## Copyright (C) Brian Moran 2005.
+##
+## 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 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, see <http://www.gnu.org/licenses/>.
+##
+######################################################################
+
+## usage: tail -f /var/log/syslog | parselog.pl | eventlogadm -o write "Application"
+
+while(<>) {
+ chomp();
+ @le = split '\s+',$_,5;
+ $ln = $le[4];
+ $cname = $le[3];
+ $outstr = sprintf "TMG: %d\nTMW: %d\nEID: 1000\nETP: INFO\nECT: 0\nRS2: 0\nCRN: 0\nUSL: 0\nSRC: Syslog\nSRN: $cname\nSTR: $ln\nDAT:\n\n",time(),time();
+ print $outstr;
+}
diff --git a/examples/scripts/idmap/README b/examples/scripts/idmap/README
new file mode 100644
index 0000000..a8637bb
--- /dev/null
+++ b/examples/scripts/idmap/README
@@ -0,0 +1,168 @@
+idmap script option for flexible UID/GID handling
+-------------------------------------------------
+
+If you are using "idmap backend = tdb2" with winbind in Samba3, then
+you have the option of specifying an external script to perform
+uid/gid allocation. This can be useful in situations where you are
+using AD for authentication, but the AD server is not configured to
+supply uid/gid mappings via the services for unix extensions and you
+have a need to support a pre-existing system for uid/gid allocation.
+
+One common situation where this arises is where you have a mixture of
+NFS and CIFS clients, and the NFS clients are configured to use NIS
+for their id mapping. It is quite common to have an administrative
+mechanism in place to ensure that all of the NIS users have a
+corresponding AD user account, but there may be no direct mechanism to
+ensure that any unix uid/gid attributes in AD match those in NIS.
+
+In this situation it would normally not be possible to share files
+with correct ownership between the CIFS and NFS clients, as winbind
+would normally allocate its own set of UIDs from a reserved pool, and
+those uids won't match the existing ones in NIS.
+
+The idmap script option
+-----------------------
+
+To resolve this problem the idmap tdb2 module has the ability to call
+out to an external script whenever it needs an unknown SID or UID/GID
+for the first time. It is then the job of that script to provide a
+mapping consistent with whatever external system is in place (such as
+NIS), and return the mapped result to winbind.
+
+Winbind will then persistently store the result of the mapping, so
+that the script is not invoked more than once per user/group.
+
+To setup the idmap script you need to set the following options:
+
+ idmap backend = tdb2
+ idmap script = /usr/local/bin/idmap.sh
+
+where the location and name of the script is arbitrary. It just needs
+to be executable by winbind.
+
+You then need to stop Samba, delete the key idmap cache files, and
+restart Samba. The idmap files that need to be deleted are:
+
+ - gencache.tdb
+ - winbindd_cache.tdb
+ - idmap2.tdb
+
+
+Script operation
+----------------
+
+The script will be called by winbind in one of three ways.
+
+ 1) idmap.sh SIDTOID <SID>
+ 2) idmap.sh IDTOSID UID <UID>
+ 2) idmap.sh IDTOSID GID <GID>
+
+In the first form the script is being asked to map a windows SID (in
+the string form "S-*") to a UID or GID. In the second form the script
+is being asked to map a UID to a SID, and in the third form it is
+being asked to map a GID to a SID.
+
+SIDTOID
+-------
+
+In the first form the script is expected to output a UID or GID given
+a SID. The output format is expected to be like this:
+
+ UID:1234
+or
+ GID:1122
+
+If the SID cannot be found, then the script should output an error
+like this:
+
+ ERR:Some error message
+
+Note that it is common for the external mechanism to not know about
+windows SIDs, in which case the script may use the wbinfo command to
+ask winbind to change the SID into a username or group name. The
+"wbinfo -s" option is the one to use.
+
+
+IDTOSID UID
+-----------
+
+In this form the script is expected to turn a UID into a SID,
+returning a result like this:
+
+ SID:S-1-5-21-1110277820-2343689819-414998773-1124
+
+or an error like this:
+
+ ERR:Some error message
+
+If the external mechanism that the script wants to use cannot produce
+a SID, but can produce a username, then the script can convert the
+username to a SID using the "wbinfo -n" option.
+
+IDTOSID GID
+-----------
+
+In this form the script is expected to turn a GID into a SID,
+returning a result like this:
+
+ SID:S-1-5-21-1110277820-2343689819-414998773-1120
+
+or an error like this:
+
+ ERR:Some error message
+
+If the external mechanism that the script wants to use cannot produce
+a SID, but can produce a group name, then the script can convert the
+groupname to a SID using the "wbinfo -n" option.
+
+
+Testing the script
+------------------
+
+It is suggested that you test the script on the command line first,
+before using it in winbind. To do that first get a list of users you
+would like to test using the command "wbinfo -u". Let's assume one of
+those users is "DC01\tridge". You would then test the script as
+follows:
+
+ [root ~]# wbinfo -n 'DC01\tridge'
+ S-1-5-21-1110277820-2343689819-414998773-1124 User (1)
+
+ [root ~]# /usr/local/bin/idmap.sh SIDTOID S-1-5-21-1110277820-2343689819-414998773-1124
+ UID:1003
+
+ [root ~]# /usr/local/bin/idmap.sh IDTOSID UID 1003
+ SID:S-1-5-21-1110277820-2343689819-414998773-1124
+
+Once those steps pass, you can enable the script in winbind
+(remembering to clear the cache tdbs), and test using the id command:
+
+ [root ~]# id 'DC01\tridge'
+ uid=1003(DC01\tridge) gid=10000009(DC01\domain users)
+
+
+nsswitch.conf
+-------------
+
+When using the idmap script option you setup nsswitch.conf as usual
+for winbind, with one addition. If your external idmap mechanism
+support nsswitch then you may optionally choose to add it to
+nsswitch.conf, but you must add it after the winbind entry. So for
+example, if using NIS, you could have a nsswitch.conf entry like this:
+
+ passwd: files winbind nis
+ group: files winbind nis
+
+Adding this to nsswitch.conf is not essential, but may be useful for
+some local administration tools.
+
+Sample script
+-------------
+
+This directory contains a simple example script 'idmap_nis.sh' that
+provides idmap script support for NIS. To use it you first need to
+enable the NIS client on your Samba server, usually by configuring
+/etc/yp.conf. See the manual page for yp.conf for details.
+
+You should test the ypcat and ypmatch commands and make sure they work
+before enabling the idmap_nis.sh script.
diff --git a/examples/scripts/idmap/idmap_nis.sh b/examples/scripts/idmap/idmap_nis.sh
new file mode 100755
index 0000000..a5ea79d
--- /dev/null
+++ b/examples/scripts/idmap/idmap_nis.sh
@@ -0,0 +1,120 @@
+#!/bin/bash
+# idmap script to map SIDs to UIDs/GIDs using NIS
+# tridge@samba.org June 2009
+
+DOMAIN=$(ypdomainname)
+
+(
+ date
+ echo $*
+) >>/var/log/samba/idmap.log
+
+cmd=$1
+shift
+
+PATH=/usr/bin:bin:$PATH
+
+shopt -s nocasematch || {
+ echo "shell option nocasematch not supported"
+ exit 1
+}
+
+# map from a domain and name to a uid/gid
+map_name()
+{
+ domain="$1"
+ name="$2"
+ ntype="$3"
+ case $ntype in
+ 1)
+ rtype="UID"
+ map="passwd"
+ ;;
+ 2)
+ rtype="GID"
+ map="group"
+ ;;
+ *)
+ echo "ERR: bad name type $ntype"
+ exit 1
+ ;;
+ esac
+ id=$(ypmatch "$name" "$map".byname 2>/dev/null | cut -d: -f3)
+ [ -z "$id" ] && {
+ echo "ERR: bad match for $name in map $map"
+ exit 1
+ }
+ echo "$rtype":"$id"
+}
+
+# map from a unix id to a name
+map_id()
+{
+ ntype="$1"
+ id="$2"
+ case $ntype in
+ UID)
+ map="passwd.byuid"
+ ;;
+ GID)
+ map="group.bygid"
+ ;;
+ *)
+ echo "ERR: bad name type $ntype"
+ exit 1
+ ;;
+ esac
+ name="$(ypmatch "$id" "$map" 2>/dev/null | cut -d: -f1)"
+ [ -z "$name" ] && {
+ echo "ERR: bad match for $name in map $map"
+ exit 1
+ }
+ echo "$name"
+}
+
+case $cmd in
+SIDTOID)
+ sid=$1
+ rid=$(echo $sid | cut -d- -f8)
+ [ -z "$rid" ] && {
+ echo "ERR: bad rid in SID $sid"
+ exit 1
+ }
+
+ unset _NO_WINBINDD
+ # oh, this is ugly. Shell is just not meant for parsing text
+ fullname=$(wbinfo -s $sid 2>/dev/null)
+ domain=$(echo $fullname | cut -d'\' -f1)
+ [[ "$domain" = $DOMAIN ]] || {
+ echo "ERR: bad domain $domain"
+ exit 1
+ }
+ name=$(echo $fullname | cut -d'\' -f2)
+ nwords=$(echo $name | wc -w)
+ ntype=$(echo $name | cut -d' ' -f$nwords)
+ nminusone=$(expr $nwords - 1)
+ name=$(echo $name | cut -d' ' -f-$nminusone)
+ [ -z "$name" ] && {
+ echo "ERR: bad name $fullname for SID $sid"
+ exit 1
+ }
+ map_name "$domain" "$name" "$ntype"
+ ;;
+IDTOSID)
+ ntype=$1
+ id=$2
+ name="$(map_id "$ntype" "$id")"
+ sid="$(wbinfo -n "$name" 2>/dev/null | cut -d' ' -f1)"
+ [ -z "$sid" ] && {
+ echo "ERR: name $name not found in ADS"
+ exit 1
+ }
+ echo "SID:$sid"
+ ;;
+*)
+ echo "ERR: Unknown command $cmd"
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/examples/scripts/mount/mount.smbfs b/examples/scripts/mount/mount.smbfs
new file mode 100644
index 0000000..3b57bc5
--- /dev/null
+++ b/examples/scripts/mount/mount.smbfs
@@ -0,0 +1,115 @@
+#!/bin/bash
+# Debian mount.smbfs compatibility wrapper
+# Copyright 2007, Steve Langasek <vorlon at debian.org>
+# Licensed under the GNU General Public License, version 2. See the
+# file /usr/share/common-licenses/GPL or <http://www.gnu.org/copyleft/gpl.txt>.
+
+# This script accepts all documented mount options for mount.smbfs,
+# passing through those that are also recognized by mount.cifs,
+# converting those that are not recognized but map to available cifs
+# options, and warning about the use of options for which no equivalent
+# exists.
+
+# known bugs: quoted spaces in arguments are not passed intact
+
+set -e
+
+# reverse the order of username and password in a "username" parameter,
+# taking care to leave any "%password" bit intact
+
+reverse_username_workgroup() {
+ local workgroup password username
+
+ username="$1"
+ case "$username" in
+ *%*) password="${username#*%}"
+ username="${username%%%*}"
+ ;;
+ *) ;;
+ esac
+ case "$username" in
+ */*) workgroup="${username#*/}"
+ username="${username%%/*}"
+ ;;
+ *) ;;
+ esac
+ if [ -n "$workgroup" ]; then
+ username="$workgroup\\$username"
+ fi
+ if [ -n "$password" ]; then
+ username="$username%$password"
+ fi
+ echo "$username"
+}
+
+
+# parse out the mount options that have been specified using -o, and if
+# necessary, convert them for use by mount.cifs
+
+parse_mount_options () {
+ local OLD_IFS IFS options option username
+ OLD_IFS="$IFS"
+ IFS=","
+ options=""
+ workgroup=""
+ password=""
+
+ for option in $@; do
+ case "$option" in
+ sockopt=* | scope=* | codepage=* | ttl=* | debug=*)
+ echo "Warning: ignoring deprecated smbfs option '$option'" >&2
+ ;;
+
+ krb)
+ options="$options${options:+,}sec=krb5"
+ ;;
+
+ guest)
+ echo "Warning: mapping 'guest' to 'guest,sec=none'" >&2
+ options="$options${options:+,}guest,sec=none"
+ ;;
+
+ # username and workgroup are reversed in username= arguments,
+ # so need to be parsed out
+ username=*/*)
+ IFS="$OLD_IFS"
+ username="${option#username=}"
+ username="$(reverse_username_workgroup "$username")"
+ IFS=","
+ options="$options${options:+,}username=$username"
+ ;;
+
+ *)
+ options="$options${options:+,}$option"
+ ;;
+ esac
+ done
+ IFS="$OLD_IFS"
+ echo $options
+}
+
+args=()
+while [ "$#" -gt 0 ]; do
+ case "$1" in
+ -o*)
+ arg=${1#-o}
+ shift
+ if [ -z "$arg" ]; then
+ arg=$1
+ shift
+ fi
+ arg="$(parse_mount_options "$arg")"
+ if [ -n "$arg" ]; then
+ args=("${args[@]}" "-o" "$arg")
+ fi
+ ;;
+ *)
+ args=("${args[@]}" "$1")
+ shift
+ ;;
+ esac
+done
+
+USER="$(reverse_username_workgroup "$USER")"
+
+exec /sbin/mount.cifs "${args[@]}"
diff --git a/examples/scripts/nmb/findsmb b/examples/scripts/nmb/findsmb
new file mode 100755
index 0000000..5c668f3
--- /dev/null
+++ b/examples/scripts/nmb/findsmb
@@ -0,0 +1,160 @@
+#!/usr/bin/env perl
+#
+# Prints info on all smb responding machines on a subnet.
+# This script needs to be run on a machine without nmbd running and be
+# run as root to get correct info from WIN95 clients.
+#
+# syntax:
+# findsmb [-d|-D] [-r] [subnet broadcast address]
+#
+# with no argument it will list machines on the current subnet
+#
+# There will be a "+" in front of the workgroup name for machines that are
+# local master browsers for that workgroup. There will be an "*" in front
+# of the workgroup name for machines that are the domain master browser for
+# that workgroup.
+#
+# Options:
+#
+# -d|-D enable debug
+# -r add -r option to nmblookup when finding netbios name
+#
+
+$SAMBABIN = "/usr/bin";
+
+for ($i = 0; $i < 2; $i++) { # test for -d and -r options
+ $_ = shift;
+ if (m/-d|-D/) {
+ $DEBUG = 1;
+ } elsif (m/-r/) {
+ $R_OPTION = "-r";
+ }
+}
+
+if ($_) { # set broadcast address if it was specified
+ $BCAST = "-B $_";
+}
+
+
+######################################################################
+# do numeric sort on last field of IP address
+sub ipsort
+{
+ @t1 = split(/\./,$a);
+ @t2 = split(/\./,$b);
+ @t1[3] <=> @t2[3];
+}
+######################################################################
+
+# look for all machines that respond to a name lookup
+
+open(NMBLOOKUP,"$SAMBABIN/nmblookup $BCAST '*' --debuglevel=0|") ||
+ die("Can't run nmblookup '*'.\n");
+
+# get rid of all lines that are not a response IP address,
+# strip everything but IP address and sort by last field in address
+
+@ipaddrs = sort ipsort grep(s/ \*<00>.*$//,<NMBLOOKUP>);
+
+# print header info
+print "\n *=DMB\n";
+print " +=LMB\n";
+print "IP ADDR NETBIOS NAME WORKGROUP/OS/VERSION $BCAST\n";
+print "---------------------------------------------------------------------\n";
+
+foreach $ip (@ipaddrs) # loop through each IP address found
+{
+ $ip =~ s/\n//; # strip newline from IP address
+
+ # find the netbios names registered by each machine
+
+ open(NMBLOOKUP,"$SAMBABIN/nmblookup $R_OPTION -A $ip --debuglevel=0|") ||
+ die("Can't get nmb name list.\n");
+ @nmblookup = <NMBLOOKUP>;
+ close NMBLOOKUP;
+
+ # get the first <00> name
+
+ @name = grep(/<00>/,@nmblookup);
+ $_ = @name[0];
+
+ if ($_) { # we have a netbios name
+ if (/GROUP/) { # is it a group name
+ ($name, $aliases, $type, $length, @addresses) =
+ gethostbyaddr(pack('C4',split('\.',$ip)),2);
+ if (! $name) { # could not get name
+ $name = "unknown nis name";
+ }
+ } else {
+ # The Netbios name can contain lot of characters also '<' '>'
+ # and spaces. The following cure inside name space but not
+ # names starting or ending with spaces
+ /(.{1,15})\s+<00>\s+/;
+ $name = $1;
+ $name =~ s/^\s+//g;
+ }
+
+ # do an smbclient command on the netbios name.
+
+ if ( "$name" ) {
+ open(SMB,"$SAMBABIN/smbclient -L $name -I $ip -N --debuglevel=1 2>&1 |") ||
+ die("Can't do smbclient command.\n");
+ @smb = <SMB>;
+ close SMB;
+
+ if ($DEBUG) { # if -d flag print results of nmblookup and smbclient
+ print "===============================================================\n";
+ print @nmblookup;
+ print @smb;
+ }
+
+ # look for the OS= string
+
+ @info = grep(/OS=/,@smb);
+ $_ = @info[0];
+ if ($_) { # we found response
+ s/Domain=|OS=|Server=|\n//g; # strip out descriptions to make line shorter
+
+ } else { # no OS= string in response (WIN95 client)
+
+ # for WIN95 clients get workgroup name from nmblookup response
+ @name = grep(/<00> - <GROUP>/,@nmblookup);
+ $_ = @name[0];
+ if ($_) {
+ # Same as before for space and characters
+ /(.{1,15})\s+<00>\s+/;
+ $_ = "[$1]";
+ } else {
+ $_ = "Unknown Workgroup";
+ }
+ }
+ }
+
+ # see if machine registered a local master browser name
+ if (grep(/<1d>/,@nmblookup)) {
+ $master = '+'; # indicate local master browser
+ if (grep(/<1b>/,@nmblookup)) { # how about domain master browser?
+ $master = '*'; # indicate domain master browser
+ }
+ } else {
+ $master = ' '; # not a browse master
+ }
+
+ # line up info in 3 columns
+
+ print "$ip".' 'x(16-length($ip))."$name".' 'x(14-length($name))."$master"."$_\n";
+
+ } else { # no netbios name found
+ # try getting the host name
+ ($name, $aliases, $type, $length, @addresses) =
+ gethostbyaddr(pack('C4',split('\.',$ip)),2);
+ if (! $name) { # could not get name
+ $name = "unknown nis name";
+ }
+ if ($DEBUG) { # if -d flag print results of nmblookup
+ print "===============================================================\n";
+ print @nmblookup;
+ }
+ print "$ip".' 'x(16-length($ip))."$name\n";
+ }
+}
diff --git a/examples/scripts/nmb/findsmb.1.xml b/examples/scripts/nmb/findsmb.1.xml
new file mode 100644
index 0000000..6b35410
--- /dev/null
+++ b/examples/scripts/nmb/findsmb.1.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
+<refentry id="findsmb.1">
+
+<refmeta>
+ <refentrytitle>findsmb</refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo class="source">Samba</refmiscinfo>
+ <refmiscinfo class="manual">User Commands</refmiscinfo>
+ <refmiscinfo class="version">&doc.version;</refmiscinfo>
+</refmeta>
+
+
+<refnamediv>
+ <refname>findsmb</refname>
+ <refpurpose>list info about machines that respond to SMB
+ name queries on a subnet</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>findsmb</command>
+ <arg choice="opt">subnet broadcast address</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This perl script is part of the <citerefentry>
+ <refentrytitle>samba</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ suite.</para>
+
+ <para><command>findsmb</command> is a perl script that
+ prints out several pieces of information about machines
+ on a subnet that respond to SMB name query requests.
+ It uses <citerefentry><refentrytitle>nmblookup</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ and <citerefentry><refentrytitle>smbclient</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ to obtain this information.
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-r</term>
+ <listitem><para>Controls whether <command>findsmb</command> takes
+ bugs in Windows95 into account when trying to find a Netbios name
+ registered of the remote machine. This option is disabled by default
+ because it is specific to Windows 95 and Windows 95 machines only.
+ If set, <citerefentry><refentrytitle>nmblookup</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ will be called with <constant>-B</constant> option.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>subnet broadcast address</term>
+ <listitem><para>Without this option, <command>findsmb
+ </command> will probe the subnet of the machine where
+ <citerefentry><refentrytitle>findsmb</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ is run. This value is passed to
+ <citerefentry><refentrytitle>nmblookup</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ as part of the <constant>-B</constant> option.</para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>EXAMPLES</title>
+
+ <para>The output of <command>findsmb</command> lists the following
+ information for all machines that respond to the initial
+ <command>nmblookup</command> for any name: IP address, NetBIOS name,
+ Workgroup name, operating system, and SMB server version.</para>
+
+ <para>There will be a '+' in front of the workgroup name for
+ machines that are local master browsers for that workgroup. There
+ will be an '*' in front of the workgroup name for
+ machines that are the domain master browser for that workgroup.
+ Machines that are running Windows for Workgroups, Windows 95 or
+ Windows 98 will
+ not show any information about the operating system or server
+ version.</para>
+
+ <para>The command with <constant>-r</constant> option
+ must be run on a system without <citerefentry>
+ <refentrytitle>nmbd</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry> running.
+
+ If <command>nmbd</command> is running on the system, you will
+ only get the IP address and the DNS name of the machine. To
+ get proper responses from Windows 95 and Windows 98 machines,
+ the command must be run as root and with <constant>-r</constant>
+ option on a machine without <command>nmbd</command> running.</para>
+
+ <para>For example, running <command>findsmb</command>
+ without <constant>-r</constant> option set would yield output similar
+ to the following</para>
+
+<programlisting>
+IP ADDR NETBIOS NAME WORKGROUP/OS/VERSION
+---------------------------------------------------------------------
+192.168.35.10 MINESET-TEST1 [DMVENGR]
+192.168.35.55 LINUXBOX *[MYGROUP] [Unix] [Samba 2.0.6]
+192.168.35.56 HERBNT2 [HERB-NT]
+192.168.35.63 GANDALF [MVENGR] [Unix] [Samba 2.0.5a for IRIX]
+192.168.35.65 SAUNA [WORKGROUP] [Unix] [Samba 1.9.18p10]
+192.168.35.71 FROGSTAR [ENGR] [Unix] [Samba 2.0.0 for IRIX]
+192.168.35.78 HERBDHCP1 +[HERB]
+192.168.35.88 SCNT2 +[MVENGR] [Windows NT 4.0] [NT LAN Manager 4.0]
+192.168.35.93 FROGSTAR-PC [MVENGR] [Windows 5.0] [Windows 2000 LAN Manager]
+192.168.35.97 HERBNT1 *[HERB-NT] [Windows NT 4.0] [NT LAN Manager 4.0]
+</programlisting>
+
+</refsect1>
+
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is part of version &doc.version; of
+ the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+ <para><citerefentry>
+ <refentrytitle>nmbd</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry><refentrytitle>smbclient</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry>, and <citerefentry><refentrytitle>nmblookup</refentrytitle>
+ <manvolnum>1</manvolnum></citerefentry>
+ </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>
+</refsect1>
+
+</refentry>
diff --git a/examples/scripts/printing/cups/smbaddprinter.pl b/examples/scripts/printing/cups/smbaddprinter.pl
new file mode 100755
index 0000000..aee2020
--- /dev/null
+++ b/examples/scripts/printing/cups/smbaddprinter.pl
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+## Add printer script for samba, APW, and cups
+## Copyright (C) Jeff Hardy <hardyjm@potsdam.edu> 2004
+##
+## 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 3 of the License, or (at your option) any
+## later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public
+## License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+@argv = @ARGV;
+
+# take in args
+my $lpname=shift(@argv); # printer name
+my $shname=shift(@argv); # share name -> used for CUPS queue name
+my $portname=shift(@argv); # port name
+my $drivername=shift(@argv); # driver name -> used for CUPS description
+my $location=shift(@argv); # location -> used for CUPS device URI
+my $win9x=shift(@argv); # win9x location
+
+#check for location syntax
+#if no protocol specified...
+if ($location !~ m#:/#){
+ #assume an lpd printer
+ $location = "lpd://".$location;
+}
+#else, simply pass the URI on to the lpadmin command
+
+#run the cups lpadmin command to add the printer
+system("/usr/sbin/lpadmin -p $shname -D \"$drivername\" -E -v $location");
+
diff --git a/examples/scripts/printing/cups/smbdelprinter.pl b/examples/scripts/printing/cups/smbdelprinter.pl
new file mode 100755
index 0000000..23adeb7
--- /dev/null
+++ b/examples/scripts/printing/cups/smbdelprinter.pl
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+## Delete printer script for samba, APW, and cups
+## Copyright (C) Gerald (Jerry) Carter <jerry@samba.rog> 2004
+##
+## 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 3 of the License, or (at your option) any
+## later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public
+## License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+@argv = @ARGV;
+
+# take in args
+my $lpname=shift(@argv); # printer name
+
+system("/usr/sbin/lpadmin -x $lpname");
+
diff --git a/examples/scripts/users_and_groups/adduserstogroups.pl b/examples/scripts/users_and_groups/adduserstogroups.pl
new file mode 100755
index 0000000..99837f9
--- /dev/null
+++ b/examples/scripts/users_and_groups/adduserstogroups.pl
@@ -0,0 +1,166 @@
+#!/usr/bin/perl
+
+#
+# adduserstogroups.pl
+#
+# add single or continuously numbered domain users
+# to a given single group or list of groups
+#
+# Copyright (C) Michael Adam <obnox@samba.org> 2007
+#
+# 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 3 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# WARNING: This script is still rather crude.
+#
+
+use strict;
+use Getopt::Std;
+
+my $net_cmd = "net";
+
+# defaults:
+
+my $server;
+my $num_members = 1;
+my $startmem; # if empty, don't add numbers to member prefix
+my $member_prefix; # name prefix for member
+my $num_groups = 1;
+my $startgroup; # if empty, don't add numbers to group prefix
+my $group_prefix; # name prefix for group
+my $path; # path to rpcclient command
+my $net_path = $net_cmd;
+my $creds;
+
+sub usage {
+ print "USAGE: $0 [-h] -S server -U user\%pass \\\n"
+ . "\t-m member [-s startmem] [-n nummem] \\\n"
+ . "\t-g group [-G startgroup] [-N numgroups] \\\n"
+ . "\t[-P path]\n";
+}
+
+# parse commandline:
+
+my %options = ();
+getopts("U:S:m:s:n:g:G:N:P:h", \%options);
+
+if (exists($options{h})) {
+ usage();
+ exit 0;
+}
+
+if (exists($options{g})) {
+ $group_prefix = $options{g};
+}
+else {
+ print "ERROR: mandatory argument '-g' missing\n";
+ usage();
+ exit 1;
+}
+
+if (exists($options{U})) {
+ $creds = "-U $options{U}";
+ if ($creds !~ '%') {
+ print "ERROR: you need to specify credentials in the form -U user\%pass\n";
+ usage();
+ exit 1;
+ }
+}
+else {
+ print "ERROR: mandatory argument '-U' missing\n";
+ usage();
+ exit 1;
+}
+
+if (exists($options{S})) {
+ $server = $options{S};
+}
+else {
+ print "ERROR: mandatory argument '-S' missing\n";
+ usage();
+ exit 1;
+}
+
+if (exists($options{s})) {
+ $startmem = $options{s};
+}
+
+if (exists($options{n})) {
+ $num_members = $options{n};
+}
+
+if (exists($options{m})) {
+ $member_prefix = $options{m};
+}
+else {
+ print "ERROR: mandatory argument '-m' missing\n";
+ usage();
+ exit 1;
+}
+
+if (exists($options{G})) {
+ $startgroup = $options{G};
+}
+
+if (exists($options{N})) {
+ $num_groups = $options{N};
+}
+
+if (exists($options{P})) {
+ $path = $options{p};
+ $net_path = "$path/$net_cmd";
+}
+
+if (@ARGV) {
+ print "ERROR: junk on the command line ('" . join(" ", @ARGV) . "')...\n";
+ usage();
+ exit 1;
+}
+
+# utility functions:
+
+sub do_add {
+ my $member_name = shift;
+ my $group_name = shift;
+ print "adding member $member_name to group $group_name\n";
+ system("$net_path rpc -I $server ".$creds." group addmem $group_name $member_name");
+}
+
+sub add_group_loop {
+ my $member_name = shift;
+
+ if ("x$startgroup" eq "x") {
+ do_add($member_name, $group_prefix);
+ }
+ else {
+ for (my $groupnum = 1; $groupnum <= $num_groups; ++$groupnum) {
+ do_add($member_name,
+ sprintf("%s%.05d", $group_prefix, $startgroup + $groupnum - 1));
+ }
+ }
+}
+
+
+# main:
+
+if ("x$startmem" eq "x") {
+ add_group_loop($member_prefix);
+}
+else {
+ for (my $memnum = 1; $memnum <= $num_members; ++$memnum) {
+ add_group_loop(sprintf("%s%.05d", $member_prefix, $startmem + $memnum - 1));
+ }
+}
+
diff --git a/examples/scripts/users_and_groups/createdomobj.pl b/examples/scripts/users_and_groups/createdomobj.pl
new file mode 100755
index 0000000..d53aefe
--- /dev/null
+++ b/examples/scripts/users_and_groups/createdomobj.pl
@@ -0,0 +1,159 @@
+#!/usr/bin/perl
+
+#
+# createdomobj.pl
+#
+# create single or continuously numbered domain
+# users/groups/aliases via rpc
+#
+# Copyright (C) Michael Adam <obnox@samba.org> 2007
+#
+# 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 3 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# WARNING: This script is still rather crude.
+#
+
+use strict;
+use Getopt::Std;
+
+
+my $target_type = "group"; # what type of object to create
+my $rpc_cmd = "createdom".$target_type;
+my $rpccli_cmd = "rpcclient";
+
+# defaults:
+
+my $server;
+my $num_targets = 1;
+my $startnum; # if empty, don't add numbers to prefix
+my $prefix; # name-prefix
+my $path; # path to rpcclient command
+my $rpccli_path = $rpccli_cmd;
+my $creds;
+
+sub usage {
+ print "USAGE: $0 [-h] -S server -U user\%pass [-p prefix] \\\n"
+ . "\t[-t {alias|group|user}] [-s startnum] [-n numobjs] [-P path] \n";
+}
+
+# parse commandline:
+
+my %options = ();
+getopts("U:t:S:s:n:p:P:h", \%options);
+
+if (exists($options{h})) {
+ usage();
+ exit 0;
+}
+
+if (exists($options{t})) {
+ $target_type = $options{t};
+ if ($target_type !~ /^(alias|user|group)$/) {
+ print "ERROR: invalid target type given\n";
+ usage();
+ exit 1;
+ }
+ $rpc_cmd = "createdom".$target_type;
+}
+
+if (exists($options{U})) {
+ $creds = "-U $options{U}";
+ if ($creds !~ '%') {
+ print "ERROR: you need to specify credentials in the form -U user\%pass\n";
+ usage();
+ exit 1;
+ }
+}
+else {
+ print "ERROR: mandatory argument '-U' missing\n";
+ usage();
+ exit 1;
+}
+
+if (exists($options{S})) {
+ $server = $options{S};
+}
+else {
+ print "ERROR: mandatory argument '-S' missing\n";
+ usage();
+ exit 1;
+}
+
+if (exists($options{s})) {
+ $startnum = $options{s};
+}
+
+if (exists($options{n})) {
+ $num_targets = $options{n};
+}
+
+if (exists($options{p})) {
+ $prefix = $options{p};
+} else {
+ $prefix = $target_type;
+}
+
+if (exists($options{P})) {
+ $path = $options{p};
+ $rpccli_path = "$path/$rpccli_cmd";
+}
+
+if (@ARGV) {
+ print "ERROR: junk on the command line ('" . join(" ", @ARGV) . "')...\n";
+ usage();
+ exit 1;
+}
+
+# utility functions:
+
+sub open_rpc_pipe {
+ print "opening rpc pipe\n";
+ open(IPC, "| $rpccli_cmd $server $creds -d0") or
+ die "error opening rpc pipe.";
+}
+
+sub close_rpc_pipe {
+ print "closing rpc pipe\n";
+ close(IPC);
+}
+
+sub do_create {
+ my $target_name = shift;
+ print "creating $target_type $target_name\n";
+ print IPC "$rpc_cmd $target_name\n";
+}
+
+# main:
+
+open_rpc_pipe();
+
+if ("x$startnum" eq "x") {
+ do_create($prefix);
+}
+else {
+ for (my $num = 1; $num <= $num_targets; ++$num) {
+ do_create(sprintf "%s%.05d", $prefix, $startnum + $num - 1);
+ if (($num) % 500 == 0) {
+ printf("500 ".$target_type."s created\n");
+ close_rpc_pipe();
+ sleep 2;
+ open_rpc_pipe();
+ }
+ }
+}
+
+close_rpc_pipe();
+
diff --git a/examples/scripts/vfs/media_harmony/trigger_avid_update.py b/examples/scripts/vfs/media_harmony/trigger_avid_update.py
new file mode 100755
index 0000000..7d724ef
--- /dev/null
+++ b/examples/scripts/vfs/media_harmony/trigger_avid_update.py
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+import os
+import socket
+import sys
+import stat
+
+######################################################################
+##
+## trigger_avid_update.py for media_harmony VFS module.
+##
+## Copyright (C) Andrew Klaassen 2012.
+##
+## 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 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, see <http://www.gnu.org/licenses/>.
+##
+######################################################################
+
+
+#
+# Change avid_shares and ip_prefix as appropriate for your network.
+#
+
+avid_shares = (
+ '\\\\mediaharmony01\\project1\\',
+ '\\\\mediaharmony01\\project2\\',
+ '\\\\mediaharmony01\\project3\\',
+)
+
+ip_prefix = '192.168.1.'
+
+
+if __name__ == "__main__":
+ my_ips = [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if ip[:len(ip_prefix)] == ip_prefix]
+ if not my_ips:
+ print 'No IP address found. Aborting.'
+ dummy = raw_input("\nPress Enter to finish: ")
+ sys.exit()
+
+ my_ip = my_ips[0]
+ my_name = os.environ.get('USERNAME')
+
+ for avid_share in avid_shares:
+ media_dirs = []
+ omfi_dir = os.path.join(avid_share, 'OMFI MediaFiles')
+ if os.path.exists(omfi_dir):
+ media_dirs.append(omfi_dir)
+ mxf_root = os.path.join(avid_share, 'Avid MediaFiles', 'MXF')
+ if os.path.exists(mxf_root):
+ mxf_children = os.listdir(mxf_root)
+ for child in mxf_children:
+ fullpath = os.path.join(mxf_root, child)
+ if os.path.isdir(fullpath):
+ media_dirs.append(fullpath)
+
+ for media_dir in media_dirs:
+
+ print '\nChecking %s...' % media_dir
+
+ fakepath = '%s_%s_%s' % (media_dir, my_ip, my_name)
+ print '...fakepath: %s' % fakepath
+
+ db = os.path.join(media_dir, 'msmMMOB.mdb')
+ print '...Checking for %s' % db
+ if os.path.exists(db):
+ print '......found %s.' % db
+ db_mtime = os.stat(db)[stat.ST_MTIME]
+ newer_file = False
+ for child in os.listdir(media_dir):
+ if child == 'msmMMOB.mdb' or child == 'msmFMID.pmr':
+ continue
+ child_mtime = os.stat(os.path.join(media_dir, child))[stat.ST_MTIME]
+ if child_mtime > db_mtime:
+ print '......found newer file %s' % child
+ newer_file = True
+ break
+ else:
+ print '......no %s.' % db
+ newer_file = True
+
+ if newer_file:
+ utime = None # Sets to current time.
+ print '...Setting fake mtime to NOW. Will trigger re-index.'
+ else:
+ mtime = os.stat(media_dir)[stat.ST_MTIME]
+ utime = (mtime, mtime)
+ print '...Setting fake mtime to media_dir mtime. No re-index.'
+
+ if not os.path.exists(fakepath):
+ tmp_fakepath = '%s.tmp' % fakepath
+ open(tmp_fakepath, 'a').close()
+ os.utime(tmp_fakepath, utime)
+ os.rename(tmp_fakepath, fakepath)
+ else:
+ os.utime(fakepath, utime)
+
+ dummy = raw_input("\nPress Enter to finish: ")
diff --git a/examples/scripts/vfs/virusfilter/virusfilter-notify.ksh b/examples/scripts/vfs/virusfilter/virusfilter-notify.ksh
new file mode 100644
index 0000000..a07b914
--- /dev/null
+++ b/examples/scripts/vfs/virusfilter/virusfilter-notify.ksh
@@ -0,0 +1,284 @@
+#!/bin/ksh
+##
+## Samba-VirusFilter VFS modules
+## Copyright (C) 2010-2016 SATOH Fumiyasu @ OSS Technology Corp., Japan
+##
+## 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 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program. If not, see <http://www.gnu.org/licenses/>.
+##
+
+set -u
+
+pdie() { echo "$0: ERROR: ${1-}" 1>&2; exit "${2-1}"; }
+
+## ======================================================================
+
+sendmail="${VIRUSFILTER_NOTIFY_SENDMAIL_COMMAND:-/usr/sbin/sendmail}"
+sendmail_opts="${VIRUSFILTER_NOTIFY_SENDMAIL_OPTIONS:-}"
+
+smbclient="${VIRUSFILTER_NOTIFY_SMBCLIENT_COMMAND:-@SAMBA_BINDIR@/smbclient}"
+smbclient_opts="${VIRUSFILTER_NOTIFY_SMBCLIENT_OPTIONS:-}"
+
+## ======================================================================
+
+if [ -n "${VIRUSFILTER_RESULT_IS_CACHE-}" ]; then
+ ## Result is cache. Ignore!
+ exit 0
+fi
+
+if [ ! -t 1 ] && [ -z "${VIRUSFILTER_NOTIFY_BG-}" ]; then
+ export VIRUSFILTER_NOTIFY_BG=1
+ "$0" ${1+"$@"} </dev/null >/dev/null &
+ exit 0
+fi
+
+## ----------------------------------------------------------------------
+
+if [ -n "${VIRUSFILTER_INFECTED_FILE_ACTION-}" ]; then
+ report="$VIRUSFILTER_INFECTED_FILE_REPORT"
+else
+ report="$VIRUSFILTER_SCAN_ERROR_REPORT"
+fi
+
+if [ X"$VIRUSFILTER_SERVER_NAME" != X"$VIRUSFILTER_SERVER_IP" ]; then
+ server_name="$VIRUSFILTER_SERVER_NAME"
+else
+ server_name="$VIRUSFILTER_SERVER_NETBIOS_NAME"
+fi
+
+if [ X"$VIRUSFILTER_CLIENT_NAME" != X"$VIRUSFILTER_CLIENT_IP" ]; then
+ client_name="$VIRUSFILTER_CLIENT_NAME"
+else
+ client_name="$VIRUSFILTER_CLIENT_NETBIOS_NAME"
+fi
+
+mail_to=""
+winpopup_to=""
+subject_prefix=""
+sender=""
+from=""
+cc=""
+bcc=""
+content_type="text/plain"
+content_encoding="UTF-8"
+
+cmd_usage="Usage: $0 [OPTIONS]
+
+Options:
+ --mail-to ADDRESS
+ Send a notice message to this e-mail address(es)
+ --winpopup-to NAME
+ Send a \"WinPopup\" message to this NetBIOS name
+ --sender ADDRESS
+ Envelope sender address for mail
+ --from ADDRESS
+ From: e-mail address for mail
+ --cc ADDRESS
+ Cc: e-mail address(es) for mail
+ --bcc ADDRESS
+ Bcc: e-mail address(es) for mail
+ --subject-prefix PREFIX
+ Subject: prefix string for mail
+ --content-type TYPE
+ --content-encoding ENCODING
+ Content-Type: TYPE; charset=\"ENCODING\" for mail [$content_type; charset=\"$content_encoding\"]
+ --header-file FILE
+ Prepend the content of FILE to the message
+ --footer-file FILE
+ Append the content of FILE to the message
+"
+
+## ----------------------------------------------------------------------
+
+getopts_want_arg()
+{
+ if [ "$#" -lt 2 ]; then
+ pdie "Option requires an argument: $1"
+ fi
+ if [ "$#" -ge 3 ]; then
+ if expr x"$2" : x"$3\$" >/dev/null; then
+ : OK
+ else
+ pdie "Invalid value for option: $1 $2"
+ fi
+ fi
+}
+
+while [ "$#" -gt 0 ]; do
+ OPT="$1"; shift
+ case "$OPT" in
+ --help)
+ echo "$cmd_usage"
+ exit 0
+ ;;
+ --mail-to)
+ getopts_want_arg "$OPT" ${1+"$1"}
+ mail_to="${mail_to:+$mail_to, }$1"; shift
+ ;;
+ --winpopup-to)
+ getopts_want_arg "$OPT" ${1+"$1"}
+ winpopup_to="$1"; shift
+ ;;
+ --sender)
+ getopts_want_arg "$OPT" ${1+"$1"}
+ sender="$1"; shift
+ ;;
+ --from)
+ getopts_want_arg "$OPT" ${1+"$1"}
+ from="$1"; shift
+ ;;
+ --cc)
+ getopts_want_arg "$OPT" ${1+"$1"}
+ cc="${cc:+$cc, }$1"; shift
+ ;;
+ --bcc)
+ getopts_want_arg "$OPT" ${1+"$1"}
+ bcc="${bcc:+$bcc, }$1"; shift
+ ;;
+ --subject-prefix)
+ getopts_want_arg "$OPT" ${1+"$1"}
+ subject_prefix="$1"; shift
+ ;;
+ --content-type)
+ getopts_want_arg "$OPT" ${1+"$1"}
+ content_type="$1"; shift
+ ;;
+ --content-encoding)
+ getopts_want_arg "$OPT" ${1+"$1"}
+ content_encoding="$1"; shift
+ ;;
+ --header-file)
+ getopts_want_arg "$OPT" ${1+"$1"}
+ header_file="$1"; shift
+ ;;
+ --footer-file)
+ getopts_want_arg "$OPT" ${1+"$1"}
+ footer_file="$1"; shift
+ ;;
+ --)
+ break
+ ;;
+ -*)
+ pdie "Invalid option: $OPT"
+ ;;
+ *)
+ set -- "$OPT" ${1+"$@"}
+ break
+ ;;
+ esac
+done
+
+[ -z "$sender" ] && sender="$from"
+subject="$subject_prefix$report"
+
+## ======================================================================
+
+msg_header="\
+Subject: $subject
+Content-Type: $content_type; charset=$content_encoding
+X-VIRUSFILTER-Version: $VIRUSFILTER_VERSION
+X-VIRUSFILTER-Module-Name: $VIRUSFILTER_MODULE_NAME
+"
+
+if [ -n "${VIRUSFILTER_MODULE_VERSION-}" ]; then
+ msg_header="${msg_header}\
+X-VIRUSFILTER-Module-Version: $VIRUSFILTER_MODULE_VERSION
+"
+fi
+
+if [ -n "${from-}" ]; then
+ msg_header="${msg_header}\
+From: $from
+"
+fi
+
+if [ -n "${mail_to-}" ]; then
+ msg_header="${msg_header}\
+To: $mail_to
+"
+fi
+
+if [ -n "${cc-}" ]; then
+ msg_header="${msg_header}\
+Cc: $cc
+"
+fi
+
+if [ -n "${bcc-}" ]; then
+ msg_header="${msg_header}\
+Bcc: $bcc
+"
+fi
+
+## ----------------------------------------------------------------------
+
+msg_body=""
+
+if [ -n "${header_file-}" ] && [ -f "$header_file" ]; then
+ msg_body="${msg_body}\
+`cat "$header_file"`
+"
+fi
+
+msg_body="${msg_body}\
+Server: $server_name ($VIRUSFILTER_SERVER_IP)
+Server PID: $VIRUSFILTER_SERVER_PID
+Service name: $VIRUSFILTER_SERVICE_NAME
+Service path: $VIRUSFILTER_SERVICE_PATH
+Client: $client_name ($VIRUSFILTER_CLIENT_IP)
+User: $VIRUSFILTER_USER_DOMAIN\\$VIRUSFILTER_USER_NAME
+"
+
+if [ -n "${VIRUSFILTER_INFECTED_FILE_ACTION-}" ]; then
+ msg_body="${msg_body}\
+Infected file report: $VIRUSFILTER_INFECTED_FILE_REPORT
+"
+ msg_body="${msg_body}\
+Infected file path: $VIRUSFILTER_SERVICE_PATH/$VIRUSFILTER_INFECTED_SERVICE_FILE_PATH
+"
+ msg_body="${msg_body}\
+Infected file action: $VIRUSFILTER_INFECTED_FILE_ACTION
+"
+else
+ msg_body="${msg_body}\
+Scan error report: $VIRUSFILTER_SCAN_ERROR_REPORT
+Scan error file path: $VIRUSFILTER_SERVICE_PATH/$VIRUSFILTER_SCAN_ERROR_SERVICE_FILE_PATH
+"
+fi
+
+if [ -n "${VIRUSFILTER_QUARANTINED_FILE_PATH-}" ]; then
+ msg_body="${msg_body}\
+Quarantined/Renamed file path: ${VIRUSFILTER_QUARANTINED_FILE_PATH-}
+"
+fi
+
+if [ -n "${footer_file-}" ] && [ -f "$footer_file" ]; then
+ msg_body="${msg_body}\
+`cat "$footer_file"`
+"
+fi
+
+## ======================================================================
+
+if [ -n "$mail_to" ]; then
+ (echo "$msg_header"; echo "$msg_body") \
+ |"$sendmail" -t -i ${sender:+-f "$sender"} $sendmail_opts
+fi
+
+if [ -n "$winpopup_to" ]; then
+ echo "$msg_body" \
+ |"$smbclient" -M "$winpopup_to" -U% $smbclient_opts \
+ >/dev/null
+fi
+
+exit 0
diff --git a/examples/scripts/wins_hook/README b/examples/scripts/wins_hook/README
new file mode 100644
index 0000000..1147f57
--- /dev/null
+++ b/examples/scripts/wins_hook/README
@@ -0,0 +1,8 @@
+This is an example script for doing dynamic DNS updates from the WINS
+database. You use this by putting the full path to the script in the
+"wins hook" option in smb.conf. Remember to mark the script executable
+and to set the right domain at the top of the script.
+
+See the BIND documentation for how to enable dynamic DNS
+updates. Remember to restrict the updates as far as you can to reduce
+the security risks inherent in dynamic DNS.
diff --git a/examples/scripts/wins_hook/dns_update b/examples/scripts/wins_hook/dns_update
new file mode 100644
index 0000000..14fc1fe
--- /dev/null
+++ b/examples/scripts/wins_hook/dns_update
@@ -0,0 +1,92 @@
+#!/bin/sh
+#
+# Example script for "wins hook". This attempts to update the DNS with
+# new A records for the NETBIOS name that Samba passes us. We do this
+# the simple way, by deleting all DNS records for the name and then
+# re-adding all the expected 'A' records.
+#
+# Written by Stephen Rothwell <sfr@linuxcare.com>
+#
+
+#
+# Configurable things
+#
+# The domain in which to create names
+# YOU MUST CHANGE THIS
+# N.B. include the trailing dot
+#
+# It is a good idea to use a subdomain of your primary domain to ensure
+# that rogue machines can't take over (or delete) important names on
+# your network.
+DOMAIN=wins.example.com.
+
+#
+# The DNS TTL to give the records (in seconds)
+#
+TTL=3600
+#
+# NETBIOS name types that we want to create DNS records for:
+# 20 is server
+# 00 is workstation
+# 03 is user
+#
+USEFUL_TYPES="20 00 03"
+#
+# The name of a cache file to use to avoid continual updates
+# of the same name and IP addresses. If you comment this out
+# then the cache is not kept at all.
+#
+#CACHE_FILE=/usr/local/samba/var/wins_update.cache
+
+if [ $# -lt 4 ]; then
+ echo "Usage: $0 op name type ttl [ip_addr ...]" 1>&2
+ echo " op is one of add, refresh, delete" 1>&2
+ echo " name is the NETBIOS name" 1>&2
+ echo " type is the NETBIOS name type" 1>&2
+ echo " ttl is the NETBIOS time to live" 1>&2
+ echo " ip_addr's are the remaining IP addresses for this name" 1>&2
+ exit 1
+fi
+
+NSUPDATE=$(which nsupdate)
+[ -x "$NSUPDATE" ] || NSUPDATE=/usr/bin/nsupdate
+[ -x "$NSUPDATE" ] || NSUPDATE=/sbin/nsupdate
+[ -x "$NSUPDATE" ] || NSUPDATE=/usr/sbin/nsupdate
+[ -x "$NSUPDATE" ] || {
+ echo "Cannot find nsupdate." 1>&2
+ exit 1
+}
+
+OP=$1
+NAME=$2
+TYPE=$3
+WINS_TTL=$4
+shift 4
+IP_ADDRS="$@"
+
+do_update=0
+for i in $USEFUL_TYPES; do
+ [ "$TYPE" = "$i" ] && do_update=1
+done
+[ $do_update = 1 ] || exit 0
+
+if [ -n "$CACHE_FILE" ]; then
+ if [ -r "$CACHE_FILE" ]; then
+ fgrep -q -x -i "$NAME $IP_ADDRS" "$CACHE_FILE" &&
+ exit 0
+ grep -v -i "^$NAME " "$CACHE_FILE" >"$CACHE_FILE".$$
+ fi
+ echo "$NAME $IP_ADDRS" >>"$CACHE_FILE".$$
+ mv "$CACHE_FILE" "$CACHE_FILE".old 2>/dev/null
+ mv "$CACHE_FILE".$$ "$CACHE_FILE"
+fi
+
+{
+ echo update delete $NAME.$DOMAIN
+ for i in $IP_ADDRS; do
+ echo update add $NAME.$DOMAIN $TTL A $i
+ done
+ echo
+} 2>/dev/null | $NSUPDATE >/dev/null 2>&1 &
+
+exit 0