diff options
Diffstat (limited to 'examples/scripts')
-rw-r--r-- | examples/scripts/debugging/linux/backtrace | 41 | ||||
-rwxr-xr-x | examples/scripts/debugging/smbXsrvdump | 87 | ||||
-rw-r--r-- | examples/scripts/debugging/solaris/README | 28 | ||||
-rw-r--r-- | examples/scripts/debugging/solaris/solaris-oops.sh | 57 | ||||
-rw-r--r-- | examples/scripts/eventlog/parselog.pl | 32 | ||||
-rw-r--r-- | examples/scripts/idmap/README | 168 | ||||
-rwxr-xr-x | examples/scripts/idmap/idmap_nis.sh | 120 | ||||
-rw-r--r-- | examples/scripts/mount/mount.smbfs | 115 | ||||
-rwxr-xr-x | examples/scripts/nmb/findsmb | 160 | ||||
-rw-r--r-- | examples/scripts/nmb/findsmb.1.xml | 145 | ||||
-rwxr-xr-x | examples/scripts/printing/cups/smbaddprinter.pl | 39 | ||||
-rwxr-xr-x | examples/scripts/printing/cups/smbdelprinter.pl | 25 | ||||
-rwxr-xr-x | examples/scripts/users_and_groups/adduserstogroups.pl | 166 | ||||
-rwxr-xr-x | examples/scripts/users_and_groups/createdomobj.pl | 159 | ||||
-rwxr-xr-x | examples/scripts/vfs/media_harmony/trigger_avid_update.py | 106 | ||||
-rw-r--r-- | examples/scripts/vfs/virusfilter/virusfilter-notify.ksh | 284 | ||||
-rw-r--r-- | examples/scripts/wins_hook/README | 8 | ||||
-rw-r--r-- | examples/scripts/wins_hook/dns_update | 92 |
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 |