diff options
Diffstat (limited to 'examples')
158 files changed, 29478 insertions, 0 deletions
diff --git a/examples/LDAP/README b/examples/LDAP/README new file mode 100644 index 0000000000..f6ce3a986e --- /dev/null +++ b/examples/LDAP/README @@ -0,0 +1,74 @@ +!== +!== README File for various LDAP examples +!== +!== written by Gerald Carter <jerry@samba.org> +!== + +OpenLDAP 2.x +------------ + +A sample schema file (samba.schema) has been included for use +with OpenLDAP 2.0.x. The OIDs used in this file are owned by +the Samba team and generated from its own Enterprise number +of 7165 (as issued by IANA). + +Copy the samba.schema file into your /etc/openldap/schema directory, +and add an include for it in the /etc/openldap/slapd.conf file. +Note that samba.schema relies upon the uid and uidNumber attributes +from the RFC2307 schema (i.e. nis.schema) + +If you choose to import /etc/passwd, nis, or nisplus tables +into ldap, you can use migration tools provided by PADL Software +which are located at + + http://www.padl.com/tools.html + +It is not a requirement that a user's /etc/passwd account +is stored in LDAP for the samba.schema file to work (although +the whole point of storing smbpasswd in LDAP is to have a +single location for user accounts, right?) + +The padl tools will leave you with LDIF files which you can import +into OpenLDAP. Before you can import them, you need to include +nis.schema and cosine.schema in your slapd.conf file. + +You must restart the LDAP server for these new included schema files +to become active. + +SunOne/Netscape DS +------------------ + +The schema file has not been updated for the sambaSamAccount +objectclass. + + +Novell eDirectory +----------------- + +The schema file has not been updated for the sambaSamAccount +objectclass. + +Fedora Directory Server / +RedHat Directory Server / +Netscape Directory Server +------------------------- + +An *updated* schema file has been provided, plus a very useful script from +Mike Jackson and Alyseo is available. +ol-schema-migrate.pl can be used to migrate OpenLDAP schema files to FDS +schema ldif files, it can also be used to validate the schema files to +make sure no duplicate OIDs or malformed entries are found. + +smbldap-tools/ +-------------- + +The smbldap-tools have been removed from the samba svn +tree. The latest version will continue to be included +in Samba releases. + +The smbldap-tools package can be downloaded individually from +https://gna.org/projects/smbldap-tools/ + +!== +!== end of README +!== diff --git a/examples/LDAP/convertSambaAccount b/examples/LDAP/convertSambaAccount new file mode 100755 index 0000000000..4357dbc8f8 --- /dev/null +++ b/examples/LDAP/convertSambaAccount @@ -0,0 +1,233 @@ +#!/usr/bin/perl -w +## +## Convert an LDIF file containing sambaAccount entries +## to the new sambaSamAccount objectclass +## +## Copyright Gerald (Jerry) Carter 2003 +## +## Usage: convertSambaAccount --sid=<Domain SID> \ +## --input=<input ldif> --output=<output ldif> \ +## --changetype=[modify|add] +## +## You can generate an input ldif file using: +## $ ldapsearch -LL -x -h ldapsrv -D cn=root,dc=company,dc=com \ +## -b dc=copmany,dc=com > /tmp/samba3.alpha23.ldif +## +## Note the "-LL" so no additional comments are generated +## + + +use strict; +use Net::LDAP::LDIF; +use Getopt::Long; + + +############################################################################## +## local variables + +my ( $domain, $domsid, $changetype ); +my ( $ldif, $ldif2 ); +my ( $entry, @objclasses, $obj ); +my ( $is_samba_account, $is_samba_group ); +my ( %attr_map, %group_attr_map, $key ); +my ( @dels, $deletion, @adds, $addition ); +my ( $result, %options ); + + +############################################################################## +## Print the option usage + +sub usage { + + print "convertSambaAccount <options>\n"; + print "Options:\n"; + print " --help print this help message\n"; + print " --input input LDIF filename\n"; + print " --output output LDIF filename\n"; + print " --sid domain SID\n"; + print " --changetype [modify|add] (default is 'add')\n"; +} + + +############################################################################## +## MAIN DRIVER ## +############################################################################## + +## +## hashes to map old attribute names to new ones +## + +%attr_map = ( + lmPassword => 'sambaLMPassword', + ntPassword => 'sambaNTPassword', + pwdLastSet => 'sambaPwdLastSet', + pwdMustChange => 'sambaPwdMustChange', + pwdCanChange => 'sambaPwdCanChange', + homeDrive => 'sambaHomeDrive', + smbHome => 'sambaHomePath', + scriptPath => 'sambaLogonScript', + profilePath => 'sambaProfilePath', + kickoffTime => 'sambaKickoffTime', + logonTime => 'sambaLogonTime', + logoffTime => 'sambaLogoffTime', + userWorkstations => 'sambaUserWorkstations', + domain => 'sambaDomainName', + acctFlags => 'sambaAcctFlags', +); + +%group_attr_map = ( + ntSid => 'sambaSID', + ntGroupType => 'sambaGroupType', +); + +## +## process command line args +## + +$result = GetOptions(\%options, + "help", + "input=s", + "output=s", + "sid=s", + "changetype=s"); + +if (!$result && ($#ARGV != -1)) { + usage(); + exit 1; +} + +if ( defined($options{'help'}) ) { + usage(); + exit 0; +} + + +if ( !defined( $options{'sid'} ) ) { + print "You must provide a domain sid\n"; + exit 1; +} + +$domsid = $options{'sid'}; + +$changetype = 'add'; +if ( defined( $options{'changetype'} ) ) { + $changetype = $options{'changetype'}; +} + +## +## open files +## + +$ldif = Net::LDAP::LDIF->new ($options{'input'}, "r") or die $!; + +if ( "$changetype" eq "add" ) { + $ldif2 = Net::LDAP::LDIF->new ($options{'output'}, "w") or die $!; +} +elsif ( "$changetype" eq "modify" ) { + open( OUTPUT, ">$options{'output'}" ) or die $!; +} +else { + print "Bad changetype!\n"; + exit 1; +} + +## +## process LDIF +## + +while ( !$ldif->eof ) { + undef ( $entry ); + $entry = $ldif->read_entry(); + + ## skip entry if we find an error + if ( $ldif->error() ) { + print "Error msg: ",$ldif->error(),"\n"; + print "Error lines:\n",$ldif->error_lines(),"\n"; + next; + } + + ## + ## check to see if we have anything to do on this + ## entry. If not just write it out + ## + @objclasses = $entry->get_value( "objectClass" ); + undef ( $is_samba_account ); + undef ( $is_samba_group ); + @adds = (); + @dels = (); + foreach $obj ( @objclasses ) { + if ( "$obj" eq "sambaAccount" ) { + $is_samba_account = 1; + } elsif ( "$obj" eq "sambaGroupMapping" ) { + $is_samba_group = 1; + } + } + + if ( defined ( $is_samba_account ) ) { + ## + ## start editing the sambaAccount + ## + + @dels = ( 'objectclass: sambaAccount', 'rid' ); + @adds = ('objectclass: sambaSamAccount', "sambaSID: " . ${domsid} . "-" . ${entry}->get_value( 'rid' ) ); + $entry->delete( 'objectclass' => [ 'sambaAccount' ] ); + $entry->add( 'objectclass' => 'sambaSamAccount' ); + + $entry->add( 'sambaSID' => $domsid."-".$entry->get_value( "rid" ) ); + $entry->delete( 'rid' ); + + if ( defined($entry->get_value( "primaryGroupID" )) ) { + push @adds, "sambaPrimaryGroupSID: " . $domsid."-".$entry->get_value( "primaryGroupID" ); + push @dels, "primaryGroupID"; + $entry->add( 'sambaPrimaryGroupSID' => $domsid."-".$entry->get_value( "primaryGroupID" ) ); + $entry->delete( 'primaryGroupID' ); + } + + + foreach $key ( keys %attr_map ) { + if ( defined($entry->get_value($key)) ) { + push @adds, "$attr_map{$key}: " . $entry->get_value($key); + push @dels, "$key"; + $entry->add( $attr_map{$key} => $entry->get_value($key) ); + $entry->delete( $key ); + } + } + } elsif ( defined ( $is_samba_group ) ) { + foreach $key ( keys %group_attr_map ) { + if ( defined($entry->get_value($key)) ) { + push @adds, "$group_attr_map{$key}: " . $entry->get_value($key); + push @dels, "$key"; + $entry->add( $group_attr_map{$key} => $entry->get_value($key) ); + $entry->delete( $key ); + } + } + } + + ## see if we should write full entries or only the changes + + if ( "$changetype" eq "add" ) { + $ldif2->write_entry( $entry ); + } + else { + if ( defined ( $is_samba_account ) || defined ( $is_samba_group ) ){ + if ( @adds + @dels > 0 ) { + print OUTPUT "dn: " . $entry->dn . "\n"; + foreach $addition (@adds) { + $addition =~ /(^\w+):/; + print OUTPUT "add: " . $1 . "\n"; + print OUTPUT "$addition\n-\n"; + } + foreach $deletion (@dels) { + if ( $deletion =~ /^(\w+):\s(.*)/ ) { + print OUTPUT "delete: $1\n$1: $2\n-\n"; + } else { + print OUTPUT "delete: $deletion\n-\n" + } + } + print OUTPUT "\n" + } + } + } +} + + diff --git a/examples/LDAP/get_next_oid b/examples/LDAP/get_next_oid new file mode 100644 index 0000000000..bf00200375 --- /dev/null +++ b/examples/LDAP/get_next_oid @@ -0,0 +1,15 @@ +#!/bin/bash + +nextattrib=`cat samba.schema | grep -i attributetype.*\(.*1.3.6.1.4.1.7165. | grep -v '^#' | \ + awk '{print $3}' | cut -d. -f 10 | sort -n | tail -1` + +(( nextattrib += 1 )) + +echo "attributetype ( 1.3.6.1.4.1.7165.2.1.$nextattrib NAME ...." + +nextoc=`cat samba.schema | grep -i objectclass.*\(.*1.3.6.1.4.1.7165. | grep -v '^#' | \ + awk '{print $3}' | cut -d. -f 10 | sort -n | tail -1` + +(( nextoc += 1 )) + +echo "objectclass ( 1.3.6.1.4.1.7165.2.2.$nextoc NAME ...." diff --git a/examples/LDAP/ol-schema-migrate.pl b/examples/LDAP/ol-schema-migrate.pl new file mode 100755 index 0000000000..12392cb4cd --- /dev/null +++ b/examples/LDAP/ol-schema-migrate.pl @@ -0,0 +1,384 @@ +#!/usr/bin/perl -w +# +# Convert OpenLDAP schema files into Fedora DS format with RFC2252 compliant printing +# +# First Release : Mike Jackson <mj@sci.fi> 14 June 2005 +# http://www.netauth.com/~jacksonm/ldap/ol-schema-migrate.pl +# Professional LDAP consulting for large and small projects +# +# - 6 Dec 2005 +# - objectclass element ordering +# +# Second Release : Alyseo <info@alyseo.com> 05 Februrary 2006 +# Francois Billard <francois@alyseo.com> +# Yacine Kheddache <yacine@alyseo.com> +# http://www.alyseo.com/ +# +# - 05 Februrary 2006 +# - parsing improvement to accept non-RFC compliant schemas (like ISPMAN) +# - adding RFC element : Usage, No-user-modification, collective keywords +# - 08 Februrary 2006 +# - adding help & usage +# - now this script can also beautify your schemas: "-b" +# - count attributes and objects class: "-c" +# - display items that can not be converted (empty OID...): "-d" +# - 15 February 2006 +# - adding workaround for Fedora DS bug 181465: +# https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=181465 +# - adding duplicated OID check: "-d" +# Useful to manually correct nasty schemas like: +# https://sourceforge.net/tracker/?func=detail&atid=108390&aid=1429276&group_id=8390 +# - 13 September 2007 +# Based on Samba Team GPL Compliance Officer request, license has been updated from +# GPL to GPLv3+ +# +# - Fedora DS bug you need to correct by hand : +# https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=179956 +# +# GPLv3+ license +# + +my $optionCount = 0; +my $optionPrint = 0; +my $optionBadEntries = 0; +my $optionHelp = 0; +my $filename = "" ; + +foreach (@ARGV) { + $optionHelp = 1 if ( /^-h$/); + $optionCount = 1 if ( /^-c$/); + $optionPrint = 1 if ( /^-b$/); + $optionBadEntries = 1 if ( /^-d$/); + $filename = $_ if ( ! /^-b$/ && ! /^-c$/ && ! /^-d$/); +} + +die "Usage : ol-schema-migrate-v2.pl [ -c ] [ -b ] [ -d ] schema\n" . + " -c\tcount attribute and object class\n" . + " -b\tconvert and beautify your schema\n" . + " -d\tdisplay unrecognized elements, find empty and duplicated OID\n" . + " -h\tthis help\n" if ($filename eq "" || ($optionHelp || (!$optionCount && !$optionPrint && !$optionBadEntries))); + +if($optionCount) { + print "Schema verification counters:\n"; + my $ldapdata = &getSourceFile($filename); + print "".(defined($ldapdata->{attributes}) ? @{$ldapdata->{attributes}} : 0) . " attributes\n"; + print "".(defined($ldapdata->{objectclass}) ? @{$ldapdata->{objectclass}} : 0) . " object classes\n\n" +} + +if($optionPrint) { + my $ldapdata = &getSourceFile($filename); + &printit($ldapdata); +} + +if($optionBadEntries) { + print "Display unrecognized entries:\n"; + my $ldapdata = &getSourceFile($filename); + my $errorsAttr = 0; + my $errorsObjc = 0; + my $errorsDup = 0; + my $emptyOid = 0; + my %dup; + + foreach (@{$ldapdata->{attributes}}) { + my $attr = $_; + + push @{$dup{$attr->{OID}}{attr}}, {NAME => $attr->{NAME}, LINENUMBER => $attr->{LINENUMBER}}; + + $attr->{DATA} =~ s/\n/ /g; + $attr->{DATA} =~ s/\r//g; + $attr->{DATA} =~ s/attribute[t|T]ypes?:?\s*\(//; + $attr->{DATA} =~ s/\Q$attr->{OID}// if(defined $attr->{OID}); + $attr->{DATA} =~ s/NAME\s*\Q$attr->{NAME}// if(defined $attr->{NAME}); + $attr->{DATA} =~ s/DESC\s*'\Q$attr->{DESC}'// if(defined $attr->{DESC}); + $attr->{DATA} =~ s/$attr->{OBSOLETE}// if(defined $attr->{OBSOLETE}); + $attr->{DATA} =~ s/SUP\s*\Q$attr->{SUP}// if(defined $attr->{SUP}); + $attr->{DATA} =~ s/EQUALITY\s*\Q$attr->{EQUALITY}// if(defined $attr->{EQUALITY}); + $attr->{DATA} =~ s/ORDERING\s*\Q$attr->{ORDERING}// if(defined $attr->{ORDERING}); + $attr->{DATA} =~ s/SUBSTR\s*\Q$attr->{SUBSTR}// if(defined $attr->{SUBSTR}); + $attr->{DATA} =~ s/SYNTAX\s*\Q$attr->{SYNTAX}// if(defined $attr->{SYNTAX}); + $attr->{DATA} =~ s/SINGLE-VALUE// if(defined $attr->{SINGLEVALUE}); + $attr->{DATA} =~ s/NO-USER-MODIFICATION// if(defined $attr->{NOUSERMOD}); + $attr->{DATA} =~ s/COLLECTIVE// if(defined $attr->{COLLECTIVE}); + $attr->{DATA} =~ s/USAGE\s*\Q$attr->{USAGE}// if(defined $attr->{USAGE}); + $attr->{DATA} =~ s/\)\s$//; + $attr->{DATA} =~ s/^\s+(\S)/\n$1/ ; + $attr->{DATA} =~ s/(\S)\s+$/$1\n/; + do { + $errorsAttr ++; + do { $emptyOid ++; + print "Warning : no OID for attributes element at line $attr->{LINENUMBER} \n"; + } if( !defined($attr->{OID})); + print "### Unknow element embedded in ATTRIBUTE at line $attr->{LINENUMBER} :\n$attr->{DATA}\n" + } if($attr->{DATA} =~ /\w/); + } + + foreach (@{$ldapdata->{objectclass}}) { + my $objc = $_; + push @{$dup{$objc->{OID}}{objc}} , {NAME => $objc->{NAME}, LINENUMBER => $objc->{LINENUMBER}}; + $objc->{DATA} =~ s/\n/ /g; + $objc->{DATA} =~ s/\r//g; + $objc->{DATA} =~ s/^object[c|C]lasse?s?:?\s*\(?//; + $objc->{DATA} =~ s/\Q$objc->{OID}// if(defined $objc->{OID}); + $objc->{DATA} =~ s/NAME\s*\Q$objc->{NAME}\E// if(defined $objc->{NAME}); + $objc->{DATA} =~ s/DESC\s*'\Q$objc->{DESC}\E'// if(defined $objc->{DESC}); + $objc->{DATA} =~ s/OBSOLETE// if(defined $objc->{OBSOLETE}); + $objc->{DATA} =~ s/SUP\s*\Q$objc->{SUP}// if(defined $objc->{SUP}); + $objc->{DATA} =~ s/\Q$objc->{TYPE}// if(defined $objc->{TYPE}); + $objc->{DATA} =~ s/MUST\s*\Q$objc->{MUST}\E\s*// if(defined $objc->{MUST}); + $objc->{DATA} =~ s/MUST\s*\(?\s*\Q$objc->{MUST}\E\s*\)?// if(defined $objc->{MUST}); + $objc->{DATA} =~ s/MAY\s*\Q$objc->{MAY}\E// if(defined $objc->{MAY}); + $objc->{DATA} =~ s/\)\s$//; + $objc->{DATA} =~ s/^\s+(\S)/\n$1/ ; + $objc->{DATA} =~ s/(\S)\s+$/$1\n/; + + do { + print "#" x 80 ."\n"; + $errorsObjc ++; + do { $emptyOid++ ; + print "Warning : no OID for object class element at line $objc->{LINENUMBER} \n"; + } if( $objc->{OID} eq ""); + print "### Unknow element embedded in OBJECT CLASS at line $objc->{LINENUMBER} :\n$objc->{DATA}\n" + } if($objc->{DATA} =~ /\w/); + } + + my $nbDup = 0; + foreach (keys %dup) { + my $sumOid = 0; + $sumOid += @{$dup{$_}{attr}} if(defined (@{$dup{$_}{attr}})); + $sumOid += @{$dup{$_}{objc}} if(defined (@{$dup{$_}{objc}})); + if( $sumOid > 1 && $_ ne "") { + $nbDup ++; + print "#" x 80 ."\n"; + print "Duplicate OID founds : $_\n"; + foreach (@{$dup{$_}{attr}}) { + + print "Attribute : $_->{NAME} (line : $_->{LINENUMBER})\n"; + } + foreach (@{$dup{$_}{objc}}) { + print "Object class : $_->{NAME} (line : $_->{LINENUMBER})\n"; + } + + } + } + + print "\n$errorsAttr errors detected in ATTRIBUTES list\n"; + print "$errorsObjc errors detected in OBJECT CLASS list\n"; + print "$nbDup duplicate OID founds\n"; + print "$emptyOid empty OID fields founds\n\n"; + +} + + +sub printit { + my $ldapdata = shift; + &printSeparator; + print "dn: cn=schema\n"; + &printSeparator; + + # print elements in RFC2252 order + + foreach (@{$ldapdata->{attributes}}) { + my $attr = $_; + print "attributeTypes: (\n"; + print " $attr->{OID}\n"; + print " NAME $attr->{NAME}\n"; + print " DESC '$attr->{DESC}'\n" if(defined $attr->{DESC}); + print " OBSOLETE\n" if(defined $attr->{OBSOLETE}); + print " SUP $attr->{SUP}\n" if(defined $attr->{SUP}); + print " EQUALITY $attr->{EQUALITY}\n" if(defined $attr->{EQUALITY}); + print " ORDERING $attr->{ORDERING}\n" if(defined $attr->{ORDERING}); + print " SUBSTR $attr->{SUBSTR}\n" if(defined $attr->{SUBSTR}); + print " SYNTAX $attr->{SYNTAX}\n" if(defined $attr->{SYNTAX}); + print " SINGLE-VALUE\n" if(defined $attr->{SINGLEVALUE}); + print " NO-USER-MODIFICATION\n" if(defined $attr->{NOUSERMOD}); + print " COLLECTIVE\n" if(defined $attr->{COLLECTIVE}); + print " USAGE $attr->{USAGE}\n" if(defined $attr->{USAGE}); + print " )\n"; + &printSeparator; + } + + foreach (@{$ldapdata->{objectclass}}) { + my $objc = $_; + # next 3 lines : Fedora DS space sensitive bug workaround + $objc->{SUP} =~ s/^\(\s*(.*?)\s*\)$/\( $1 \)/ if (defined $objc->{SUP}); + $objc->{MUST} =~ s/^\(\s*(.*?)\s*\)$/\( $1 \)/ if (defined $objc->{MUST}); + $objc->{MAY} =~ s/^\(\s*(.*?)\s*\)$/\( $1 \)/ if (defined $objc->{MAY}); + + print "objectClasses: (\n"; + print " $objc->{OID}\n"; + print " NAME $objc->{NAME}\n"; + print " DESC '$objc->{DESC}'\n" if(defined $objc->{DESC}); + print " OBSOLETE\n" if(defined $objc->{OBSOLETE}); + print " SUP $objc->{SUP}\n" if(defined $objc->{SUP}); + print " $objc->{TYPE}\n" if(defined $objc->{TYPE}); + print " MUST $objc->{MUST}\n" if(defined $objc->{MUST}); + print " MAY $objc->{MAY}\n" if(defined $objc->{MAY}); + print " )\n"; + &printSeparator; + } +} + +sub printSeparator { + print "#\n"; + print "#" x 80 . "\n"; + print "#\n"; +} + +sub getSourceFile { + my @data = &getFile(shift); + my %result; + my $result = \%result; + my @allattrs; + my @allattrsLineNumber; + my @allobjc; + my @allobjcLineNumber; + my $at = 0; + my $oc = 0; + my $at_string; + my $oc_string; + my $idx = 0; + my $beginParenthesis = 0; + my $endParenthesis = 0; + my $lineNumber = 0; + for(@data) { + $lineNumber++; + next if (/^\s*\#/); # skip comments + + if($at) { + s/ +/ /; # remove embedded tabs + s/\t/ /; # remove multiple spaces after the $ sign + + $at_string .= $_; + $beginParenthesis = 0; # Use best matching elements + $endParenthesis = 0; + for(my $i=0;$ i < length($at_string); $i++) { + $beginParenthesis++ if(substr ($at_string,$i,1) eq "("); + $endParenthesis++ if(substr ($at_string,$i,1) eq ")"); + } + if($beginParenthesis == $endParenthesis) { + push @allattrs, $at_string; + $at = 0; + $at_string = ""; + $endParenthesis = 0; + $beginParenthesis = 0; + } + } + + if (/^attribute[t|T]ype/) { + my $line = $_; + push @allattrsLineNumber, $lineNumber; # keep starting line number + for(my $i=0;$ i < length($line); $i++) { + $beginParenthesis++ if(substr ($line, $i, 1) eq "("); + $endParenthesis++ if(substr ($line, $i, 1) eq ")"); + } + if($beginParenthesis == $endParenthesis && $beginParenthesis != 0) { + push @allattrs, $line; + $endParenthesis = 0; + $beginParenthesis = 0; + } else { + $at_string = $line; + $at = 1; + } + } + + ##################################### + + if($oc) { + s/ +/ /; + s/\t/ /; + + $oc_string .= $_; + $endParenthesis = 0; # best methode to accept an elements : + $beginParenthesis = 0; # left parenthesis sum == right parenthesis sum, so we are sure to + for(my $i=0;$ i < length($oc_string); $i++) { # have an element. + $beginParenthesis++ if(substr ($oc_string, $i, 1) eq "("); + $endParenthesis++ if(substr ($oc_string, $i, 1) eq ")"); + } + if($beginParenthesis == $endParenthesis) { + push @allobjc, $oc_string; + $oc = 0; + $oc_string = ""; + $endParenthesis = 0; + $beginParenthesis = 0; + } + } + + if (/^object[c|C]lass/) { + my $line = $_; + push @allobjcLineNumber, $lineNumber; # keep starting line number + for(my $i=0;$ i < length($line); $i++) { + $beginParenthesis++ if(substr ($line, $i, 1) eq "("); + $endParenthesis++ if(substr ($line, $i, 1) eq ")"); + } + if($beginParenthesis == $endParenthesis && $beginParenthesis != 0) { + push @allobjc, $line; + $endParenthesis = 0; + $beginParenthesis = 0; + } else { + $oc_string = $line; + $oc = 1; + } + } + } + + # Parsing attribute elements + + for(@allattrs) { + s/\n/ /g; + s/\r//g; + s/ +/ /g; + s/\t/ /g; + $result->{attributes}->[$idx]->{DATA} = $_ if($optionBadEntries); # keep original data + $result->{attributes}->[$idx]->{LINENUMBER} = $allattrsLineNumber[$idx]; + $result->{attributes}->[$idx]->{OID} = $1 if (m/^attribute[t|T]ypes?:?\s*\(?\s*([\.\d]*?)\s+/); + $result->{attributes}->[$idx]->{NAME} = $1 if (m/NAME\s+('.*?')\s*/ || m/NAME\s+(\(.*?\))/); + $result->{attributes}->[$idx]->{DESC} = $1 if (m/DESC\s+'(.*?)'\s*/); + $result->{attributes}->[$idx]->{OBSOLETE} = "OBSOLETE" if (m/OBSOLETE/); + $result->{attributes}->[$idx]->{SUP} = $1 if (m/SUP\s+(.*?)\s/); + $result->{attributes}->[$idx]->{EQUALITY} = $1 if (m/EQUALITY\s+(.*?)\s/); + $result->{attributes}->[$idx]->{ORDERING} = $1 if (m/ORDERING\s+(.*?)\s/); + $result->{attributes}->[$idx]->{SUBSTR} = $1 if (m/SUBSTR\s+(.*?)\s/); + $result->{attributes}->[$idx]->{SYNTAX} = $1 if (m/SYNTAX\s+(.*?)(\s|\))/); + $result->{attributes}->[$idx]->{SINGLEVALUE} = "SINGLE-VALUE" if (m/SINGLE-VALUE/); + $result->{attributes}->[$idx]->{COLLECTIVE} = "COLLECTIVE" if (m/COLLECTIVE/); + $result->{attributes}->[$idx]->{USAGE} = $1 if (m/USAGE\s+(.*?)\s/); + $result->{attributes}->[$idx]->{NOUSERMOD} = "NO-USER-MODIFICATION" if (m/NO-USER-MODIFICATION/); + $idx ++; + } + + $idx = 0; + + # Parsing object class elements + + for(@allobjc) { + s/\n/ /g; + s/\r//g; + s/ +/ /g; + s/\t/ /g; + $result->{objectclass}->[$idx]->{DATA} = $_ if($optionBadEntries); # keep original data + $result->{objectclass}->[$idx]->{LINENUMBER} = $allobjcLineNumber[$idx]; + $result->{objectclass}->[$idx]->{OID} = $1 if (m/^object[c|C]lasse?s?:?\s*\(?\s*([\.\d]*?)\s+/); + $result->{objectclass}->[$idx]->{NAME} = $1 if (m/NAME\s+('.*?')\s*/ || m/NAME\s+(\(.*?\))/); + $result->{objectclass}->[$idx]->{DESC} = $1 if (m/DESC\s+'(.*?)'\s*/); + $result->{objectclass}->[$idx]->{OBSOLETE} = "OBSOLETE" if (m/OBSOLETE/); + $result->{objectclass}->[$idx]->{SUP} = $1 if (m/SUP\s+([^()]+?)\s/ || m/SUP\s+(\(.+?\))\s/); + $result->{objectclass}->[$idx]->{TYPE} = $1 if (m/((?:STRUCTURAL)|(?:AUXILIARY)|(?:ABSTRACT))/); + $result->{objectclass}->[$idx]->{MUST} = $1 if (m/MUST\s+(\w+)\)?/ || m/MUST\s+(\(.*?\))(\s|\))/s); + $result->{objectclass}->[$idx]->{MAY} = $1 if (m/MAY\s+(\w+)\)?/ || m/MAY\s+(\(.*?\))(\s|\))/s); + + $idx++; + } + + return $result; +} + +sub getFile { + my @data; + my $file = shift; + die "File not found : $file\n" if(! -e $file); + open FH, $file; + @data = <FH>; + close FH; + @data; +} + diff --git a/examples/LDAP/samba-nds.schema b/examples/LDAP/samba-nds.schema new file mode 100644 index 0000000000..8e8c5bcdf3 --- /dev/null +++ b/examples/LDAP/samba-nds.schema @@ -0,0 +1,361 @@ +## +## Schema file for Novell eDirectory by Uli Iske +## Schema for storing Samba user accounts and group maps in LDAP +## OIDs are owned by the Samba Team +## +## Prerequisite schemas rfc2307-usergroup.ldif +## +## 1.3.6.1.4.1.7165.2.1.x - attributetypes +## 1.3.6.1.4.1.7165.2.2.x - objectclasses +## +## OIDs are owned by the Samba Team +## +####################################################################### +## Attributes used by Samba 3.0 schema ## +####################################################################### + +## +## Password hashes +## + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword' DESC 'LanManager Password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword' DESC 'MD4 hash of the unicode password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) + +## +## Account flags in string format ((UWDX ]) +## + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags' DESC 'Account Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE ) + +## +## Password timestamps & policies +## + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet' DESC 'Timestamp of the last password update' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange' DESC 'Timestamp of when the user is allowed to update the password' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange' DESC 'Timestamp of when the password will expire' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime' DESC 'Timestamp of last logon' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime' DESC 'Timestamp of last logoff' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime' DESC 'Timestamp of when the user will be logged off automatically' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount' DESC 'Bad password attempt count' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime' DESC 'Time of the last bad password attempt' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.55 NAME 'sambaLogonHours' DESC 'Logon Hours' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +## +## String settings +## + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive' DESC 'Driver letter of home directory mapping' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript' DESC 'Logon script path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath' DESC 'Roaming profile path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations' DESC 'List of user workstations the user is allowed to logon to' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath' DESC 'Home directory UNC path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName' DESC 'Windows NT domain to which the user belongs' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' DESC 'Base64 encoded user parameter string' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory' DESC 'Concatenated MD4 hashes of the unicode passwords used on this account' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{1024} ) + +## +## SID, of any type +## + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID' DESC 'Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE ) + +## +## Primary group SID, compatible with ntSid +## + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID' DESC 'Primary Group Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.51 NAME 'sambaSIDList' DESC 'Security ID List' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} ) + +## +## group mapping attributes +## + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType' DESC 'NT Group Type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +## +## Store info on domain +## + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid' DESC 'Next NT rid to give our for users' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid' DESC 'Next NT rid to give out for groups' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid' DESC 'Next NT rid to give out for anything' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' DESC 'Base at which the samba RID generation algorithm should operate' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName' DESC 'Share Name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName' DESC 'Option Name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption' DESC 'A boolean option' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption' DESC 'An integer option' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption' DESC 'A string option' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption' DESC 'A string list option' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) + +## +## unused +## +## dn: cn=schema +## changetype: modify +## add: attributetypes +## attributeTypes: ( 1.3.6.1.4.1.7165.2.1.50 NAME 'sambaPrivName' SUP name ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.52 NAME 'sambaPrivilegeList' DESC 'Privileges List' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags' DESC 'Trust Password Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.58 NAME 'sambaMinPwdLength' DESC 'Minimal password length (default: 5)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.59 NAME 'sambaPwdHistoryLength' DESC 'Length of Password History Entries (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.60 NAME 'sambaLogonToChgPwd' DESC 'Force Users to logon for password change (default: 0 => off, 2 => on)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.61 NAME 'sambaMaxPwdAge' DESC 'Maximum password age, in seconds (default: -1 => never expire passwords)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.62 NAME 'sambaMinPwdAge' DESC 'Minimum password age, in seconds (default: 0 => allow immediate password change)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.63 NAME 'sambaLockoutDuration' DESC 'Lockout duration in minutes (default: 30, -1 => forever)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.64 NAME 'sambaLockoutObservationWindow' DESC 'Reset time after lockout in minutes (default: 30)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.65 NAME 'sambaLockoutThreshold' DESC 'Lockout users after bad logon attempts (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff' DESC 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +dn: cn=schema +changetype: modify +add: attributetypes +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwdChange' DESC 'Allow Machine Password changes (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + + +####################################################################### +## objectClasses used by Samba 3.0 schema ## +####################################################################### + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' DESC 'Samba 3.0 Auxilary SAM Account' SUP top AUXILIARY MUST ( uid $ sambaSID ) MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $ sambaBadPasswordCount $ sambaBadPasswordTime $ sambaPasswordHistory $ sambaLogonHours)) + +## +## Group mapping info +## + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' DESC 'Samba Group Mapping' SUP top AUXILIARY MUST ( gidNumber $ sambaSID $ sambaGroupType ) MAY ( displayName $ description $ sambaSIDList)) + +## +## Trust password for trust relationships (any kind) +## + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.7165.2.2.14 NAME 'sambaTrustPassword' DESC 'Samba Trust Password' SUP top STRUCTURAL MUST ( sambaDomainName $ sambaNTPassword $ sambaTrustFlags ) MAY ( sambaSID $ sambaPwdLastSet )) + +## +## Whole-of-domain info +## + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' DESC 'Samba Domain Information' SUP top STRUCTURAL MUST ( sambaDomainName $ sambaSID ) MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $ sambaAlgorithmicRidBase $ sambaMinPwdLength $ sambaPwdHistoryLength $ sambaLogonToChgPwd $ sambaMaxPwdAge $ sambaMinPwdAge $ sambaLockoutDuration $ sambaLockoutObservationWindow $ sambaLockoutThreshold $ sambaForceLogoff $ sambaRefuseMachinePwdChange )) + +## +## used for idmap_ldap module +## + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.7 NAME 'sambaUnixIdPool' DESC 'Pool for allocating UNIX uids/gids' SUP top AUXILIARY MUST ( uidNumber $ gidNumber )) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.8 NAME 'sambaIdmapEntry' DESC 'Mapping from a SID to an ID' SUP top AUXILIARY MUST ( sambaSID ) MAY ( uidNumber $ gidNumber )) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' DESC 'Structural Class for a SID' SUP top STRUCTURAL MUST ( sambaSID )) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.10 NAME 'sambaConfig' DESC 'Samba Configuration Section' SUP top AUXILIARY MAY ( description )) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.7165.2.2.11 NAME 'sambaShare' DESC 'Samba Share Section' SUP top STRUCTURAL MUST ( sambaShareName ) MAY ( description )) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' DESC 'Samba Configuration Option' SUP top STRUCTURAL MUST ( sambaOptionName ) MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ sambaStringListoption $ description )) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.7165.2.2.13 NAME 'sambaPrivilege' DESC 'Samba Privilege' SUP top AUXILIARY MUST ( sambaSID ) MAY ( sambaPrivilegeList )) diff --git a/examples/LDAP/samba-schema-FDS.ldif b/examples/LDAP/samba-schema-FDS.ldif new file mode 100644 index 0000000000..e88559fc8a --- /dev/null +++ b/examples/LDAP/samba-schema-FDS.ldif @@ -0,0 +1,156 @@ +## schema file for Fedora/RedHat Directory Server +## +## NOTE: this file can be copied as 60samba.ldif into your instance schema +## directory: +## cp samba-schema-FDS.ldif /etc/dirsrv/slapd-<instance-name>/schema/60schema.ldif +## +## Schema for storing Samba user accounts and group maps in LDAP +## OIDs are owned by the Samba Team +## +## Prerequisite schemas - uid (cosine.schema) +## - displayName (inetorgperson.schema) +## - gidNumber (nis.schema) +## +## 1.3.6.1.4.1.7165.2.1.x - attributeTypess +## 1.3.6.1.4.1.7165.2.2.x - objectClasseses +## +## Printer support +## 1.3.6.1.4.1.7165.2.3.1.x - attributeTypess +## 1.3.6.1.4.1.7165.2.3.2.x - objectClasseses +## +## Samba4 +## 1.3.6.1.4.1.7165.4.1.x - attributeTypess +## 1.3.6.1.4.1.7165.4.2.x - objectClasseses +## 1.3.6.1.4.1.7165.4.3.x - LDB/LDAP Controls +## 1.3.6.1.4.1.7165.4.4.x - LDB/LDAP Extended Operations +## 1.3.6.1.4.1.7165.4.255.x - mapped OIDs due to conflicts between AD and standards-track +## +dn: cn=schema +## +####################################################################### +## Attributes used by Samba 3.0 schema ## +####################################################################### +## +## Password hashes## +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword' DESC 'LanManager Password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword' DESC 'MD4 hash of the unicode password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +## +## Account flags in string format ([UWDX ]) +## +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags' DESC 'Account Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE ) +## +## Password timestamps & policies +## +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet' DESC 'Timestamp of the last password update' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange' DESC 'Timestamp of when the user is allowed to update the password' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange' DESC 'Timestamp of when the password will expire' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime' DESC 'Timestamp of last logon' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime' DESC 'Timestamp of last logoff' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime' DESC 'Timestamp of when the user will be logged off automatically' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount' DESC 'Bad password attempt count' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime' DESC 'Time of the last bad password attempt' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.55 NAME 'sambaLogonHours' DESC 'Logon Hours' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{42} SINGLE-VALUE ) +## +## string settings +## +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive' DESC 'Driver letter of home directory mapping' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript' DESC 'Logon script path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath' DESC 'Roaming profile path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations' DESC 'List of user workstations the user is allowed to logon to' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath' DESC 'Home directory UNC path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName' DESC 'Windows NT domain to which the user belongs' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' DESC 'Base64 encoded user parameter string' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory' DESC 'Concatenated MD5 hashes of the salted NT passwords used on this account' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} ) +## +## SID, of any type +## +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID' DESC 'Security ID' EQUALITY caseIgnoreIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE ) +## +## Primary group SID, compatible with ntSid +## +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID' DESC 'Primary Group Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.51 NAME 'sambaSIDList' DESC 'Security ID List' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} ) +## +## group mapping attributes +## +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType' DESC 'NT Group Type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +## +## Store info on the domain +## +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid' DESC 'Next NT rid to give our for users' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid' DESC 'Next NT rid to give out for groups' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid' DESC 'Next NT rid to give out for anything' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' DESC 'Base at which the samba RID generation algorithm should operate' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName' DESC 'Share Name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName' DESC 'Option Name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption' DESC 'A boolean option' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption' DESC 'An integer option' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption' DESC 'A string option' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption' DESC 'A string list option' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +##attributeTypes: ( 1.3.6.1.4.1.7165.2.1.50 NAME 'sambaPrivName' +## SUP name ) +## +##attributeTypes: ( 1.3.6.1.4.1.7165.2.1.52 NAME 'sambaPrivilegeList' +## DESC 'Privileges List' +## EQUALITY caseIgnoreIA5Match +## SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags' DESC 'Trust Password Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) +# "min password length" +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.58 NAME 'sambaMinPwdLength' DESC 'Minimal password length (default: 5)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +# "password history" +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.59 NAME 'sambaPwdHistoryLength' DESC 'Length of Password History Entries (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +# "user must logon to change password" +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.60 NAME 'sambaLogonToChgPwd' DESC 'Force Users to logon for password change (default: 0 => off, 2 => on)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +# "maximum password age" +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.61 NAME 'sambaMaxPwdAge' DESC 'Maximum password age, in seconds (default: -1 => never expire passwords)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +# "minimum password age" +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.62 NAME 'sambaMinPwdAge' DESC 'Minimum password age, in seconds (default: 0 => allow immediate password change)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +# "lockout duration" +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.63 NAME 'sambaLockoutDuration' DESC 'Lockout duration in minutes (default: 30, -1 => forever)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +# "reset count minutes" +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.64 NAME 'sambaLockoutObservationWindow' DESC 'Reset time after lockout in minutes (default: 30)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +# "bad lockout attempt" +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.65 NAME 'sambaLockoutThreshold' DESC 'Lockout users after bad logon attempts (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +# "disconnect time" +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff' DESC 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +# "refuse machine password change" +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwdChange' DESC 'Allow Machine Password changes (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +## +####################################################################### +## objectClasses: used by Samba 3.0 schema ## +####################################################################### +## +## The X.500 data model (and therefore LDAPv3) says that each entry can +## only have one structural objectClasses. OpenLDAP 2.0 does not enforce +## this currently but will in v2.1 +## +## added new objectClasses: (and OID) for 3.0 to help us deal with backwards +## compatibility with 2.2 installations (e.g. ldapsam_compat) --jerry +## +objectClasses: ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY DESC 'Samba 3.0 Auxilary SAM Account' MUST ( uid $ sambaSID ) MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $ sambaBadPasswordCount $ sambaBadPasswordTime $ sambaPasswordHistory $ sambaLogonHours)) +## +## Group mapping info +## +objectClasses: ( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY DESC 'Samba Group Mapping' MUST ( gidNumber $ sambaSID $ sambaGroupType ) MAY ( displayName $ description $ sambaSIDList )) +## +## Trust password for trust relationships (any kind) +## +objectClasses: ( 1.3.6.1.4.1.7165.2.2.14 NAME 'sambaTrustPassword' SUP top STRUCTURAL DESC 'Samba Trust Password' MUST ( sambaDomainName $ sambaNTPassword $ sambaTrustFlags ) MAY ( sambaSID $ sambaPwdLastSet )) +## +## Whole-of-domain info +## +objectClasses: ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL DESC 'Samba Domain Information' MUST ( sambaDomainName $ sambaSID ) MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $ sambaAlgorithmicRidBase $ sambaMinPwdLength $ sambaPwdHistoryLength $ sambaLogonToChgPwd $ sambaMaxPwdAge $ sambaMinPwdAge $ sambaLockoutDuration $ sambaLockoutObservationWindow $ sambaLockoutThreshold $ sambaForceLogoff $ sambaRefuseMachinePwdChange )) +## +## used for idmap_ldap module +## +objectClasses: ( 1.3.6.1.4.1.7165.2.2.7 NAME 'sambaUnixIdPool' SUP top AUXILIARY DESC 'Pool for allocating UNIX uids/gids' MUST ( uidNumber $ gidNumber ) ) +objectClasses: ( 1.3.6.1.4.1.7165.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIARY DESC 'Mapping from a SID to an ID' MUST ( sambaSID ) MAY ( uidNumber $ gidNumber ) ) +objectClasses: ( 1.3.6.1.4.1.7165.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL DESC 'Structural Class for a SID' MUST ( sambaSID ) ) +objectClasses: ( 1.3.6.1.4.1.7165.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY DESC 'Samba Configuration Section' MAY ( description ) ) +objectClasses: ( 1.3.6.1.4.1.7165.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL DESC 'Samba Share Section' MUST ( sambaShareName ) MAY ( description ) ) +objectClasses: ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL DESC 'Samba Configuration Option' MUST ( sambaOptionName ) MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ sambaStringListoption $ description ) ) +## retired during privilege rewrite +##objectClasses: ( 1.3.6.1.4.1.7165.2.2.13 NAME 'sambaPrivilege' SUP top AUXILIARY +## DESC 'Samba Privilege' +## MUST ( sambaSID ) +## MAY ( sambaPrivilegeList ) ) diff --git a/examples/LDAP/samba-schema-netscapeds4.x b/examples/LDAP/samba-schema-netscapeds4.x new file mode 100644 index 0000000000..9f40966418 --- /dev/null +++ b/examples/LDAP/samba-schema-netscapeds4.x @@ -0,0 +1,112 @@ +# +# LDAP Schema file for SAMBA 3.0 attribute storage +# For Netscape Directory Server 4.1x +# Prepared by Osman Demirhan + +attribute sambaLMPassword 1.3.6.1.4.1.7165.2.1.24 cis single +attribute sambaNTPassword 1.3.6.1.4.1.7165.2.1.25 cis single +attribute sambaAcctFlags 1.3.6.1.4.1.7165.2.1.26 cis single +attribute sambaPwdLastSet 1.3.6.1.4.1.7165.2.1.27 int single +attribute sambaPwdCanChange 1.3.6.1.4.1.7165.2.1.28 int single +attribute sambaPwdMustChange 1.3.6.1.4.1.7165.2.1.29 int single +attribute sambaLogonTime 1.3.6.1.4.1.7165.2.1.30 int single +attribute sambaLogoffTime 1.3.6.1.4.1.7165.2.1.31 int single +attribute sambaKickoffTime 1.3.6.1.4.1.7165.2.1.32 int single +attribute sambaHomeDrive 1.3.6.1.4.1.7165.2.1.33 cis single +attribute sambaLogonScript 1.3.6.1.4.1.7165.2.1.34 cis single +attribute sambaProfilePath 1.3.6.1.4.1.7165.2.1.35 cis single +attribute sambaUserWorkstations 1.3.6.1.4.1.7165.2.1.36 cis single +attribute sambaHomePath 1.3.6.1.4.1.7165.2.1.37 cis single +attribute sambaDomainName 1.3.6.1.4.1.7165.2.1.38 cis single +attribute sambaSID 1.3.6.1.4.1.7165.2.1.20 cis single +attribute sambaPrimaryGroupSID 1.3.6.1.4.1.7165.2.1.23 cis single +attribute sambaGroupType 1.3.6.1.4.1.7165.2.1.19 int single +attribute sambaNextUserRid 1.3.6.1.4.1.7165.2.1.21 int single +attribute sambaNextGroupRid 1.3.6.1.4.1.7165.2.1.22 int single +attribute sambaNextRid 1.3.6.1.4.1.7165.2.1.39 int single +attribute sambaAlgorithmicRidBase 1.3.6.1.4.1.7165.2.1.40 int single + +objectclass sambaSamAccount + oid + 1.3.6.1.4.1.7165.2.2.6 + superior + top + requires + objectClass, + uid, + sambaSID + allows + cn, + sambaLMPassword, + sambaNTPassword, + sambaPwdLastSet, + sambaLogonTime, + sambaLogoffTime, + sambaKickoffTime, + sambaPwdCanChange, + sambaPwdMustChange, + sambaAcctFlags, + displayName, + sambaHomePath, + sambaHomeDrive, + sambaLogonScript, + sambaProfilePath, + description, + sambaUserWorkstations, + sambaPrimaryGroupSID, + sambaDomainName + +objectclass sambaGroupMapping + oid + 1.3.6.1.4.1.7165.2.2.4 + superior + top + requires + gidNumber, + sambaSID, + sambaGroupType + allows + displayName, + description + +objectclass sambaDomain + oid + 1.3.6.1.4.1.7165.2.2.5 + superior + top + requires + sambaDomainName, + sambaSID + allows + sambaNextRid, + sambaNextGroupRid, + sambaNextUserRid, + sambaAlgorithmicRidBase + +objectclass sambaUnixIdPool + oid + 1.3.6.1.4.1.7165.1.2.2.7 + superior + top + requires + uidNumber, + gidNumber + +objectclass sambaIdmapEntry + oid + 1.3.6.1.4.1.7165.1.2.2.8 + superior + top + requires + sambaSID + allows + uidNumber, + gidNumber + +objectclass sambaSidEntry + oid + 1.3.6.1.4.1.7165.1.2.2.9 + superior + top + requires + sambaSID diff --git a/examples/LDAP/samba-schema-netscapeds5.x b/examples/LDAP/samba-schema-netscapeds5.x new file mode 100644 index 0000000000..efc528b786 --- /dev/null +++ b/examples/LDAP/samba-schema-netscapeds5.x @@ -0,0 +1,62 @@ +## +## Darren Chew <darren.chew at vicscouts dot asn dot au> +## Andre Fiebach <andre dot fiebach at stud dot uni-rostock dot de> +## Thomas Mueller 12.04.2003, thomas.mueller@christ-wasser.de +## Richard Renard rrenard@idealx.com 2005-01-28 +## - added support for MungedDial, BadPasswordCount, BadPasswordTime, PasswordHistory, LogonHours +## - in Sun One 5.2 copy it as 99samba-schema-netscapeds5.ldif +## +## Samba 3.0 schema file for Netscape DS 5.x +## +## INSTALL-DIRECTORY/slapd-your_name/config/schema/samba-schema-netscapeds5.ldif +#################################################################### +# Sun One DS do not load the schema without this lines +# André Fiebach <af123@uni-rostock.de> +dn: cn=schema +objectClass: top +objectClass: ldapSubentry +objectClass: subschema +cn: schema +aci: (target="ldap:///cn=schema")(targetattr !="aci")(version 3.0;acl "anonymo + us, no acis"; allow (read, search, compare) userdn = "ldap:///anyone";) +aci: (targetattr = "*")(version 3.0; acl "Configuration Administrator"; allow + (all) userdn = "ldap:///uid=admin,ou=Administrators, ou=TopologyManagement, + o=NetscapeRoot";) +aci: (targetattr = "*")(version 3.0; acl "Local Directory Administrators Group + "; allow (all) groupdn = "ldap:///cn=Directory Administrators, dc=samba,dc=org";) +aci: (targetattr = "*")(version 3.0; acl "SIE Group"; allow (all)groupdn = "ld + ap:///cn=slapd-sambaldap, cn=iPlanet Directory Server, cn=Server Group, cn=iPlanetDirectory.samba.org, ou=samba.org, o=NetscapeRoot";) +#################################################################### +objectClasses: ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY DESC 'Samba 3.0 Auxilary SAM Account' MUST ( uid $ sambaSID ) MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $ sambaBadPasswordCount $ sambaBadPasswordTime $ sambaPasswordHistory $ sambaLogonHours) X-ORIGIN 'user defined' ) +objectClasses: ( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY DESC 'Samba Group Mapping' MUST ( gidNumber $ sambaSID $ sambaGroupType ) MAY ( displayName $ description ) X-ORIGIN 'user defined' ) +objectClasses: ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL DESC 'Samba Domain Information' MUST ( sambaDomainName $ sambaSID ) MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $ sambaAlgorithmicRidBase ) X-ORIGIN 'user defined' ) +objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.7 NAME 'sambaUnixIdPool' SUP top AUXILIARY DESC 'Pool for allocating UNIX uids/gids' MUST ( uidNumber $ gidNumber ) X-ORIGIN 'user defined' ) +objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIARY DESC 'Mapping from a SID to an ID' MUST ( sambaSID ) MAY ( uidNumber $ gidNumber ) X-ORIGIN 'user defined' ) +objectClasses: ( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL DESC 'Structural Class for a SID' MUST ( sambaSID ) X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword' DESC 'LanManager Password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword' DESC 'MD4 hash of the unicode password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags' DESC 'Account Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet' DESC 'Timestamp of the last password update' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange' DESC 'Timestamp of when the user is allowed to update the password' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange' DESC 'Timestamp of when the password will expire' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime' DESC 'Timestamp of last logon' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime' DESC 'Timestamp of last logoff' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime' DESC 'Timestamp of when the user will be logged off automatically' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive' DESC 'Driver letter of home directory mapping' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript' DESC 'Logon script path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath' DESC 'Roaming profile path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations' DESC 'List of user workstations the user is allowed to logon to' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath' DESC 'Home directory UNC path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName' DESC 'Windows NT domain to which the user belongs' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' DESC 'Base64 encoded user parameter string' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount' DESC 'Bad password attempt count' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime' DESC 'Time of the last bad password attempt' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory' DESC 'Concatenated MD4 hashes of the unicode passwords used on this account' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.55 NAME 'sambaLogonHours' DESC 'Logon Hours' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{42} SINGLE-VALUE ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID' DESC 'Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID' DESC 'Primary Group Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType' DESC 'NT Group Type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid' DESC 'Next NT rid to give our for users' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid' DESC 'Next NT rid to give out for groups' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid' DESC 'Next NT rid to give out for anything' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' DESC 'Base at which the samba RID generation algorithm should operate' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) diff --git a/examples/LDAP/samba-schema.IBMSecureWay b/examples/LDAP/samba-schema.IBMSecureWay new file mode 100644 index 0000000000..1fca4a749a --- /dev/null +++ b/examples/LDAP/samba-schema.IBMSecureWay @@ -0,0 +1,43 @@ +## +## Submitted by Dirk Kastens <Dirk.Kastens@Uni-Osnabrueck.de> +## +## I translated the samba.schema to be used with IBM +## SecureWay directoy server 3.2.2. You have to load +## it in your slapd32.conf with: +## +## dn: cn=IBM SecureWay, cn=Schemas, cn=Configuration +## cn: IBM SecureWay +## ibm-slapdIncludeSchema: /etc/lapschema/samba.schema +## +objectClasses { +( 1.3.1.5.1.4.1.7165.2.2.2 NAME 'sambaAccount' DESC 'Samba Account' SUP top MUST uid $ rid MAY ( acctFlags $ cn $ description $ displayName $ homeDrive $ kickoffTime $ lmPassword $ logoffTime $ logonTime $ ntPassword $ primaryGroupID $ profilePath $ pwdCanChange $ pwdLastSet $ pwdMustChange $ scriptPath $ smbHome $ userWorkstations ) ) +} + +attributeTypes { +( 1.3.6.1.4.1.7165.2.1.1 NAME 'lmPassword' DESC 'LanManager Passwd' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.10 NAME 'homeDrive' DESC 'NT homeDrive' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.11 NAME 'scriptPath' DESC 'NT scriptPath' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.12 NAME 'profilePath' DESC 'NT profilePath' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.13 NAME 'userWorkstations' DESC 'userWorkstations' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.14 NAME 'rid' DESC 'NT rid' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID' DESC 'NT Group RID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.17 NAME 'smbHome' DESC 'smbHome' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} ) +( 1.3.6.1.4.1.7165.2.1.2 NAME 'ntPassword' DESC 'NT Passwd' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.3 NAME 'pwdLastSet' DESC 'NT pwdLastSet' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.4 NAME 'acctFlags' DESC 'Account Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.5 NAME 'logonTime' DESC 'NT logonTime' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.6 NAME 'logoffTime' DESC 'NT logoffTime' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.7 NAME 'kickoffTime' DESC 'NT kickoffTime' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.8 NAME 'pwdCanChange' DESC 'NT pwdCanChange' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +( 1.3.6.1.4.1.7165.2.1.9 NAME 'pwdMustChange' DESC 'NT pwdMustChange' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +} + +IBMattributeTypes { +} + +ldapSyntaxes { +} + +matchingRules { +} + diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema new file mode 100644 index 0000000000..8f82dddeb3 --- /dev/null +++ b/examples/LDAP/samba.schema @@ -0,0 +1,575 @@ +## +## schema file for OpenLDAP 2.x +## Schema for storing Samba user accounts and group maps in LDAP +## OIDs are owned by the Samba Team +## +## Prerequisite schemas - uid (cosine.schema) +## - displayName (inetorgperson.schema) +## - gidNumber (nis.schema) +## +## 1.3.6.1.4.1.7165.2.1.x - attributetypes +## 1.3.6.1.4.1.7165.2.2.x - objectclasses +## +## Printer support +## 1.3.6.1.4.1.7165.2.3.1.x - attributetypes +## 1.3.6.1.4.1.7165.2.3.2.x - objectclasses +## +## Samba4 +## 1.3.6.1.4.1.7165.4.1.x - attributetypes +## 1.3.6.1.4.1.7165.4.2.x - objectclasses +## 1.3.6.1.4.1.7165.4.3.x - LDB/LDAP Controls +## 1.3.6.1.4.1.7165.4.4.x - LDB/LDAP Extended Operations +## 1.3.6.1.4.1.7165.4.255.x - mapped OIDs due to conflicts between AD and standards-track +## +## ----- READ THIS WHEN ADDING A NEW ATTRIBUTE OR OBJECT CLASS ------ +## +## Run the 'get_next_oid' bash script in this directory to find the +## next available OID for attribute type and object classes. +## +## $ ./get_next_oid +## attributetype ( 1.3.6.1.4.1.7165.2.1.XX NAME .... +## objectclass ( 1.3.6.1.4.1.7165.2.2.XX NAME .... +## +## Also ensure that new entries adhere to the declaration style +## used throughout this file +## +## <attributetype|objectclass> ( 1.3.6.1.4.1.7165.2.XX.XX NAME .... +## ^ ^ ^ +## +## The spaces are required for the get_next_oid script (and for +## readability). +## +## ------------------------------------------------------------------ + +# objectIdentifier SambaRoot 1.3.6.1.4.1.7165 +# objectIdentifier Samba3 SambaRoot:2 +# objectIdentifier Samba3Attrib Samba3:1 +# objectIdentifier Samba3ObjectClass Samba3:2 +# objectIdentifier Samba4 SambaRoot:4 + +######################################################################## +## HISTORICAL ## +######################################################################## + +## +## Password hashes +## +#attributetype ( 1.3.6.1.4.1.7165.2.1.1 NAME 'lmPassword' +# DESC 'LanManager Passwd' +# EQUALITY caseIgnoreIA5Match +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.2 NAME 'ntPassword' +# DESC 'NT Passwd' +# EQUALITY caseIgnoreIA5Match +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) + +## +## Account flags in string format ([UWDX ]) +## +#attributetype ( 1.3.6.1.4.1.7165.2.1.4 NAME 'acctFlags' +# DESC 'Account Flags' +# EQUALITY caseIgnoreIA5Match +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE ) + +## +## Password timestamps & policies +## +#attributetype ( 1.3.6.1.4.1.7165.2.1.3 NAME 'pwdLastSet' +# DESC 'NT pwdLastSet' +# EQUALITY integerMatch +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.5 NAME 'logonTime' +# DESC 'NT logonTime' +# EQUALITY integerMatch +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.6 NAME 'logoffTime' +# DESC 'NT logoffTime' +# EQUALITY integerMatch +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.7 NAME 'kickoffTime' +# DESC 'NT kickoffTime' +# EQUALITY integerMatch +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.8 NAME 'pwdCanChange' +# DESC 'NT pwdCanChange' +# EQUALITY integerMatch +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.9 NAME 'pwdMustChange' +# DESC 'NT pwdMustChange' +# EQUALITY integerMatch +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +## +## string settings +## +#attributetype ( 1.3.6.1.4.1.7165.2.1.10 NAME 'homeDrive' +# DESC 'NT homeDrive' +# EQUALITY caseIgnoreIA5Match +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.11 NAME 'scriptPath' +# DESC 'NT scriptPath' +# EQUALITY caseIgnoreIA5Match +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.12 NAME 'profilePath' +# DESC 'NT profilePath' +# EQUALITY caseIgnoreIA5Match +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.13 NAME 'userWorkstations' +# DESC 'userWorkstations' +# EQUALITY caseIgnoreIA5Match +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.17 NAME 'smbHome' +# DESC 'smbHome' +# EQUALITY caseIgnoreIA5Match +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.18 NAME 'domain' +# DESC 'Windows NT domain to which the user belongs' +# EQUALITY caseIgnoreIA5Match +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} ) + +## +## user and group RID +## +#attributetype ( 1.3.6.1.4.1.7165.2.1.14 NAME 'rid' +# DESC 'NT rid' +# EQUALITY integerMatch +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +#attributetype ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID' +# DESC 'NT Group RID' +# EQUALITY integerMatch +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +## +## The smbPasswordEntry objectclass has been depreciated in favor of the +## sambaAccount objectclass +## +#objectclass ( 1.3.6.1.4.1.7165.2.2.1 NAME 'smbPasswordEntry' SUP top AUXILIARY +# DESC 'Samba smbpasswd entry' +# MUST ( uid $ uidNumber ) +# MAY ( lmPassword $ ntPassword $ pwdLastSet $ acctFlags )) + +#objectclass ( 1.3.6.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTURAL +# DESC 'Samba Account' +# MUST ( uid $ rid ) +# MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $ +# logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $ +# displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $ +# description $ userWorkstations $ primaryGroupID $ domain )) + +#objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY +# DESC 'Samba Auxiliary Account' +# MUST ( uid $ rid ) +# MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $ +# logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $ +# displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $ +# description $ userWorkstations $ primaryGroupID $ domain )) + +######################################################################## +## END OF HISTORICAL ## +######################################################################## + +####################################################################### +## Attributes used by Samba 3.0 schema ## +####################################################################### + +## +## Password hashes +## +attributetype ( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword' + DESC 'LanManager Password' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword' + DESC 'MD4 hash of the unicode password' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) + +## +## Account flags in string format ([UWDX ]) +## +attributetype ( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags' + DESC 'Account Flags' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE ) + +## +## Password timestamps & policies +## +attributetype ( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet' + DESC 'Timestamp of the last password update' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange' + DESC 'Timestamp of when the user is allowed to update the password' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange' + DESC 'Timestamp of when the password will expire' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime' + DESC 'Timestamp of last logon' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime' + DESC 'Timestamp of last logoff' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime' + DESC 'Timestamp of when the user will be logged off automatically' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount' + DESC 'Bad password attempt count' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime' + DESC 'Time of the last bad password attempt' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.55 NAME 'sambaLogonHours' + DESC 'Logon Hours' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{42} SINGLE-VALUE ) + +## +## string settings +## +attributetype ( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive' + DESC 'Driver letter of home directory mapping' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript' + DESC 'Logon script path' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath' + DESC 'Roaming profile path' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations' + DESC 'List of user workstations the user is allowed to logon to' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath' + DESC 'Home directory UNC path' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName' + DESC 'Windows NT domain to which the user belongs' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' + DESC 'Base64 encoded user parameter string' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory' + DESC 'Concatenated MD5 hashes of the salted NT passwords used on this account' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} ) + +## +## SID, of any type +## + +attributetype ( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID' + DESC 'Security ID' + EQUALITY caseIgnoreIA5Match + SUBSTR caseExactIA5SubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE ) + +## +## Primary group SID, compatible with ntSid +## + +attributetype ( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID' + DESC 'Primary Group Security ID' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.51 NAME 'sambaSIDList' + DESC 'Security ID List' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} ) + +## +## group mapping attributes +## +attributetype ( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType' + DESC 'NT Group Type' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +## +## Store info on the domain +## + +attributetype ( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid' + DESC 'Next NT rid to give our for users' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid' + DESC 'Next NT rid to give out for groups' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid' + DESC 'Next NT rid to give out for anything' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' + DESC 'Base at which the samba RID generation algorithm should operate' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName' + DESC 'Share Name' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName' + DESC 'Option Name' + EQUALITY caseIgnoreMatch + SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption' + DESC 'A boolean option' + EQUALITY booleanMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption' + DESC 'An integer option' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption' + DESC 'A string option' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption' + DESC 'A string list option' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) + + +##attributetype ( 1.3.6.1.4.1.7165.2.1.50 NAME 'sambaPrivName' +## SUP name ) + +##attributetype ( 1.3.6.1.4.1.7165.2.1.52 NAME 'sambaPrivilegeList' +## DESC 'Privileges List' +## EQUALITY caseIgnoreIA5Match +## SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags' + DESC 'Trust Password Flags' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +# "min password length" +attributetype ( 1.3.6.1.4.1.7165.2.1.58 NAME 'sambaMinPwdLength' + DESC 'Minimal password length (default: 5)' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +# "password history" +attributetype ( 1.3.6.1.4.1.7165.2.1.59 NAME 'sambaPwdHistoryLength' + DESC 'Length of Password History Entries (default: 0 => off)' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +# "user must logon to change password" +attributetype ( 1.3.6.1.4.1.7165.2.1.60 NAME 'sambaLogonToChgPwd' + DESC 'Force Users to logon for password change (default: 0 => off, 2 => on)' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +# "maximum password age" +attributetype ( 1.3.6.1.4.1.7165.2.1.61 NAME 'sambaMaxPwdAge' + DESC 'Maximum password age, in seconds (default: -1 => never expire passwords)' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +# "minimum password age" +attributetype ( 1.3.6.1.4.1.7165.2.1.62 NAME 'sambaMinPwdAge' + DESC 'Minimum password age, in seconds (default: 0 => allow immediate password change)' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +# "lockout duration" +attributetype ( 1.3.6.1.4.1.7165.2.1.63 NAME 'sambaLockoutDuration' + DESC 'Lockout duration in minutes (default: 30, -1 => forever)' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +# "reset count minutes" +attributetype ( 1.3.6.1.4.1.7165.2.1.64 NAME 'sambaLockoutObservationWindow' + DESC 'Reset time after lockout in minutes (default: 30)' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +# "bad lockout attempt" +attributetype ( 1.3.6.1.4.1.7165.2.1.65 NAME 'sambaLockoutThreshold' + DESC 'Lockout users after bad logon attempts (default: 0 => off)' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +# "disconnect time" +attributetype ( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff' + DESC 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +# "refuse machine password change" +attributetype ( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwdChange' + DESC 'Allow Machine Password changes (default: 0 => off)' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +# +attributetype ( 1.3.6.1.4.1.7165.2.1.68 NAME 'sambaClearTextPassword' + DESC 'Clear text password (used for trusted domain passwords)' + EQUALITY octetStringMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) + +# +attributetype ( 1.3.6.1.4.1.7165.2.1.69 NAME 'sambaPreviousClearTextPassword' + DESC 'Previous clear text password (used for trusted domain passwords)' + EQUALITY octetStringMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) + + + +####################################################################### +## objectClasses used by Samba 3.0 schema ## +####################################################################### + +## The X.500 data model (and therefore LDAPv3) says that each entry can +## only have one structural objectclass. OpenLDAP 2.0 does not enforce +## this currently but will in v2.1 + +## +## added new objectclass (and OID) for 3.0 to help us deal with backwards +## compatibility with 2.2 installations (e.g. ldapsam_compat) --jerry +## +objectclass ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY + DESC 'Samba 3.0 Auxilary SAM Account' + MUST ( uid $ sambaSID ) + MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ + sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ + sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ + displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ + sambaProfilePath $ description $ sambaUserWorkstations $ + sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $ + sambaBadPasswordCount $ sambaBadPasswordTime $ + sambaPasswordHistory $ sambaLogonHours)) + +## +## Group mapping info +## +objectclass ( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY + DESC 'Samba Group Mapping' + MUST ( gidNumber $ sambaSID $ sambaGroupType ) + MAY ( displayName $ description $ sambaSIDList )) + +## +## Trust password for trust relationships (any kind) +## +objectclass ( 1.3.6.1.4.1.7165.2.2.14 NAME 'sambaTrustPassword' SUP top STRUCTURAL + DESC 'Samba Trust Password' + MUST ( sambaDomainName $ sambaNTPassword $ sambaTrustFlags ) + MAY ( sambaSID $ sambaPwdLastSet )) + +## +## Trust password for trusted domains +## (to be stored beneath the trusting sambaDomain object in the DIT) +## +objectclass ( 1.3.6.1.4.1.7165.2.2.15 NAME 'sambaTrustedDomainPassword' SUP top STRUCTURAL + DESC 'Samba Trusted Domain Password' + MUST ( sambaDomainName $ sambaSID $ + sambaClearTextPassword $ sambaPwdLastSet ) + MAY ( sambaPreviousClearTextPassword )) + +## +## Whole-of-domain info +## +objectclass ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL + DESC 'Samba Domain Information' + MUST ( sambaDomainName $ + sambaSID ) + MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $ + sambaAlgorithmicRidBase $ + sambaMinPwdLength $ sambaPwdHistoryLength $ sambaLogonToChgPwd $ + sambaMaxPwdAge $ sambaMinPwdAge $ + sambaLockoutDuration $ sambaLockoutObservationWindow $ sambaLockoutThreshold $ + sambaForceLogoff $ sambaRefuseMachinePwdChange )) + +## +## used for idmap_ldap module +## +objectclass ( 1.3.6.1.4.1.7165.2.2.7 NAME 'sambaUnixIdPool' SUP top AUXILIARY + DESC 'Pool for allocating UNIX uids/gids' + MUST ( uidNumber $ gidNumber ) ) + + +objectclass ( 1.3.6.1.4.1.7165.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIARY + DESC 'Mapping from a SID to an ID' + MUST ( sambaSID ) + MAY ( uidNumber $ gidNumber ) ) + +objectclass ( 1.3.6.1.4.1.7165.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL + DESC 'Structural Class for a SID' + MUST ( sambaSID ) ) + +objectclass ( 1.3.6.1.4.1.7165.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY + DESC 'Samba Configuration Section' + MAY ( description ) ) + +objectclass ( 1.3.6.1.4.1.7165.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL + DESC 'Samba Share Section' + MUST ( sambaShareName ) + MAY ( description ) ) + +objectclass ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL + DESC 'Samba Configuration Option' + MUST ( sambaOptionName ) + MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ + sambaStringListoption $ description ) ) + + +## retired during privilege rewrite +##objectclass ( 1.3.6.1.4.1.7165.2.2.13 NAME 'sambaPrivilege' SUP top AUXILIARY +## DESC 'Samba Privilege' +## MUST ( sambaSID ) +## MAY ( sambaPrivilegeList ) ) diff --git a/examples/LDAP/samba.schema.at.IBM-DS b/examples/LDAP/samba.schema.at.IBM-DS new file mode 100644 index 0000000000..4f4c0567a9 --- /dev/null +++ b/examples/LDAP/samba.schema.at.IBM-DS @@ -0,0 +1,99 @@ +## Samba 3.0 schema for IBM Directory Server 5.1 - object classes only + +attributetypes=( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword' DESC 'LanManager Password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +IBMAttributetypes=( 1.3.6.1.4.1.7165.2.1.24 DBNAME( 'sambaLMPassword' 'sambaLMPassword' ) ACCESS-CLASS critical ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword' DESC 'MD4 hash of the unicode password'EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE ) +IBMAttributetypes=( 1.3.6.1.4.1.7165.2.1.25 DBNAME( 'sambaNTPassword' 'sambaNTPassword' ) ACCESS-CLASS critical ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags' DESC 'Account Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet' DESC 'Timestamp of the last password update' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange' DESC 'Timestamp of when the user is allowed to update the password' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange' DESC 'Timestamp of when the password will expire' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime' DESC 'Timestamp of last logon' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime' DESC 'Timestamp of last logoff' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime' DESC 'Timestamp of when the user will be logged off automatically' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive' DESC 'Driver letter of home directory mapping' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript' DESC 'Logon script path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath' DESC 'Roaming profile path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations' DESC 'List of user workstations the user is allowed to logon to' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath' DESC 'Home directory UNC path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName' DESC 'Windows NT domain to which the user belongs' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID' DESC 'Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID' DESC 'Primary Group Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType' DESC 'NT Group Type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid' DESC 'Next NT rid to give our for users' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid' DESC 'Next NT rid to give out for groups' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid' DESC 'Next NT rid to give out for anything' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' DESC 'Base at which the samba RID generation algorithm should operate' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName' DESC 'Share Name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName' DESC 'Option Name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption' DESC 'A boolean option' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption' DESC 'An integer option' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption' DESC 'A string option' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption' DESC 'A string list option' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' DESC 'Base64 encoded user parameter string' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount' DESC 'Bad password attempt count' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime' DESC 'Time of the last bad password attempt' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.51 NAME 'sambaSIDList' DESC 'Security ID List' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags' DESC 'Trust Password Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory' DESC 'Concatenated MD4 hashes of the unicode passwords used on this account' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} ) +IBMAttributetypes=( 1.3.6.1.4.1.7165.2.1.54 DBNAME( 'sambaPasswordHistory' 'sambaPasswordHistory' ) ACCESS-CLASS critical ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.55 NAME 'sambaLogonHours' DESC 'Logon Hours' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{42} SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.56 NAME 'sambaAccountPolicyName' DESC 'Account Policy Name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.57 NAME 'sambaAccountPolicyValue' DESC 'Account Policy Value' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.58 NAME 'sambaMinPwdLength' DESC 'Minimal password length (default: 5)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.59 NAME 'sambaPwdHistoryLength' DESC 'Length of Password History Entries (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.60 NAME 'sambaLogonToChgPwd' DESC 'Force Users to logon for password change (default: 0 => off, 2 => on)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.61 NAME 'sambaMaxPwdAge' DESC 'Maximum password age, in seconds (default: -1 => never expire passwords)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.62 NAME 'sambaMinPwdAge' DESC 'Minimum password age, in seconds (default: 0 => allow immediate password change)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.63 NAME 'sambaLockoutDuration' DESC 'Lockout duration in minutes (default: 30, -1 => forever)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.64 NAME 'sambaLockoutObservationWindow' DESC 'Reset time after lockout in minutes (default: 30)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.65 NAME 'sambaLockoutThreshold' DESC 'Lockout users after bad logon attempts (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff' DESC 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwdChange' DESC 'Allow Machine Password changes (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + diff --git a/examples/LDAP/samba.schema.oc.IBM-DS b/examples/LDAP/samba.schema.oc.IBM-DS new file mode 100644 index 0000000000..575aed4b1a --- /dev/null +++ b/examples/LDAP/samba.schema.oc.IBM-DS @@ -0,0 +1,23 @@ +## Samba 3.0 schema for IBM Directory Server 5.1 - object classes only + +objectclasses=( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY DESC 'Samba 3.0 Auxilary SAM Account' MUST ( uid $ sambaSID ) MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $ sambaBadPasswordCount $ sambaBadPasswordTime $ sambaPasswordHistory $ sambaLogonHours)) + +objectclasses=( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY DESC 'Samba Group Mapping' MUST ( gidNumber $ sambaSID $ sambaGroupType ) MAY ( displayName $ description $ sambaSIDList )) + +objectclasses=( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL DESC 'Samba Domain Information' MUST ( sambaDomainName $ sambaSID ) MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $ sambaAlgorithmicRidBase $ sambaMinPwdLength $ sambaPwdHistoryLength $ sambaLogonToChgPwd $ sambaMaxPwdAge $ sambaMinPwdAge $ sambaLockoutDuration $ sambaLockoutObservationWindow $ sambaLockoutThreshold $ sambaForceLogoff $ sambaRefuseMachinePwdChange ) ) + +objectclasses=( 1.3.6.1.4.1.7165.1.2.2.7 NAME 'sambaUnixIdPool' SUP top AUXILIARY DESC 'Pool for allocating UNIX uids/gids' MUST ( uidNumber $ gidNumber ) ) + +objectclasses=( 1.3.6.1.4.1.7165.1.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIARY DESC 'Mapping from a SID to an ID' MUST ( sambaSID ) MAY ( uidNumber $ gidNumber ) ) + +objectclasses=( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL DESC 'Structural Class for a SID' MUST ( sambaSID ) ) + +objectclasses=( 1.3.6.1.4.1.7165.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY DESC 'Samba Configuration Section' MAY ( description ) ) + +objectclasses=( 1.3.6.1.4.1.7165.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL DESC 'Samba Share Section' MUST ( sambaShareName ) MAY ( description ) ) + +objectclasses=( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL DESC 'Samba Configuration Option' MUST ( sambaOptionName ) MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ sambaStringListoption $ description ) ) + +objectclasses=( 1.3.6.1.4.1.7165.2.2.14 NAME 'sambaTrustPassword' SUP top STRUCTURAL DESC 'Samba Trust Password' MUST ( sambaDomainName $ sambaNTPassword $ sambaTrustFlags ) MAY ( sambaSID $ sambaPwdLastSet )) + +objectclasses=( 1.3.6.1.4.1.7165.2.2.15 NAME 'sambaAccountPolicy' SUP top STRUCTURAL DESC 'Samba Account Policy' MUST ( sambaAccountPolicyName $ sambaAccountPolicyValue ) MAY ( description ) ) diff --git a/examples/README b/examples/README new file mode 100644 index 0000000000..2222606714 --- /dev/null +++ b/examples/README @@ -0,0 +1,11 @@ +Copyright(C) Samba-Team 1993-2001 + +This directory contains example config files and related material for +Samba. + +At a minimum please refer to the smb.conf.default file for current +information regarding global and share parameter settings. + +Send additions to: samba@samba.org + + diff --git a/examples/VFS/Makefile.in b/examples/VFS/Makefile.in new file mode 100644 index 0000000000..4de0efd29e --- /dev/null +++ b/examples/VFS/Makefile.in @@ -0,0 +1,51 @@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LDSHFLAGS = @LDSHFLAGS@ +INSTALLCMD = @INSTALL@ +SAMBA_SOURCE = @SAMBA_SOURCE@ +SHLIBEXT = @SHLIBEXT@ +OBJEXT = @OBJEXT@ +FLAGS = $(CFLAGS) $(CPPFLAGS) -fPIC \ + -Iinclude -I$(SAMBA_SOURCE)/include \ + -I$(SAMBA_SOURCE)/popt \ + -I$(SAMBA_SOURCE)/lib/replace \ + -I$(SAMBA_SOURCE)/lib/talloc \ + -I$(SAMBA_SOURCE)/lib/tdb/include \ + -I$(SAMBA_SOURCE)/smbwrapper \ + -I$(SAMBA_SOURCE)/librpc \ + -I$(SAMBA_SOURCE) -I. + + +prefix = @prefix@ +libdir = @libdir@ + +VFS_LIBDIR = $(libdir)/vfs + +# Auto target +default: $(patsubst %.c,%.$(SHLIBEXT),$(wildcard *.c)) + +# Pattern rules + +%.$(SHLIBEXT): %.$(OBJEXT) + @echo "Linking $@" + @$(CC) $(LDSHFLAGS) $(LDFLAGS) -o $@ $< + +%.$(OBJEXT): %.c + @echo "Compiling $<" + @$(CC) $(FLAGS) -c $< + + +install: default + $(INSTALLCMD) -d $(VFS_LIBDIR) + $(INSTALLCMD) -m 755 *.$(SHLIBEXT) $(VFS_LIBDIR) + +# Misc targets +clean: + rm -rf .libs + rm -f core *~ *% *.bak *.o *.$(SHLIBEXT) + +distclean: clean + rm -f config.status config.cache Makefile + diff --git a/examples/VFS/README b/examples/VFS/README new file mode 100644 index 0000000000..2f6196d117 --- /dev/null +++ b/examples/VFS/README @@ -0,0 +1,20 @@ +README for Samba Virtual File System (VFS) Example +=================================================== + +This directory contains skeleton VFS modules. When used, +this module simply passes all requests back to the disk functions +(i.e it operates as a passthrough filter). It should be +useful as a starting point for developing new VFS +modules. + +Please look at skel_opaque.c when you want your module to provide +final functions, like a database filesystem. + +Please look at skel_transport.c when you want your module to provide +passthrough functions, like audit modules. + +Please read the VFS chapter in the HOWTO collection for general help +on the usage of VFS modules. + +Further documentation on writing VFS modules for Samba can be found in +Samba Developers Guide. diff --git a/examples/VFS/autogen.sh b/examples/VFS/autogen.sh new file mode 100755 index 0000000000..223919890f --- /dev/null +++ b/examples/VFS/autogen.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +# Run this script to build samba from SVN. + +## insert all possible names (only works with +## autoconf 2.x +TESTAUTOHEADER="autoheader autoheader-2.53 autoheader2.50" +TESTAUTOCONF="autoconf autoconf-2.53 autoconf2.50" + +AUTOHEADERFOUND="0" +AUTOCONFFOUND="0" + + +## +## Look for autoheader +## +for i in $TESTAUTOHEADER; do + if which $i > /dev/null 2>&1; then + if [ `$i --version | head -n 1 | cut -d. -f 2 | tr -d [:alpha:]` -ge 53 ]; then + AUTOHEADER=$i + AUTOHEADERFOUND="1" + break + fi + fi +done + +## +## Look for autoconf +## + +for i in $TESTAUTOCONF; do + if which $i > /dev/null 2>&1; then + if [ `$i --version | head -n 1 | cut -d. -f 2 | tr -d [:alpha:]` -ge 53 ]; then + AUTOCONF=$i + AUTOCONFFOUND="1" + break + fi + fi +done + + +## +## do we have it? +## +if [ "$AUTOCONFFOUND" = "0" -o "$AUTOHEADERFOUND" = "0" ]; then + echo "$0: need autoconf 2.53 or later to build samba from SVN" >&2 + exit 1 +fi + +rm -rf autom4te*.cache + +echo "$0: running $AUTOHEADER" +$AUTOHEADER || exit 1 + +echo "$0: running $AUTOCONF" +$AUTOCONF || exit 1 + +rm -rf autom4te*.cache + +echo "Now run ./configure and then make." +exit 0 + diff --git a/examples/VFS/config.guess b/examples/VFS/config.guess new file mode 100755 index 0000000000..600580b1aa --- /dev/null +++ b/examples/VFS/config.guess @@ -0,0 +1,1463 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-09-19' + +# This file 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/>. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner <per@bothner.com>. +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <features.h> + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include <sys/param.h> +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess +and + http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/examples/VFS/config.sub b/examples/VFS/config.sub new file mode 100755 index 0000000000..23cd6fd75c --- /dev/null +++ b/examples/VFS/config.sub @@ -0,0 +1,1577 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-07-08' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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/>. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ms1 \ + | msp430 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m32c) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | ms1-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + m32c-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/examples/VFS/configure.in b/examples/VFS/configure.in new file mode 100644 index 0000000000..b8e10d482b --- /dev/null +++ b/examples/VFS/configure.in @@ -0,0 +1,359 @@ +dnl -*- mode: m4-mode -*- +dnl Process this file with autoconf to produce a configure script. + +dnl We must use autotools 2.53 or above +AC_PREREQ(2.53) +AC_INIT(Makefile.in) + +AC_CONFIG_HEADER(module_config.h) +#dnl To make sure that didn't get #define PACKAGE_* in modules_config.h +#echo "" > confdefs.h + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_INSTALL +AC_CANONICAL_HOST + +################################################# +# Directory handling stuff to support both the +# legacy SAMBA directories and FHS compliant +# ones... +AC_PREFIX_DEFAULT(/usr/local/samba) + +AC_ARG_WITH(fhs, +[ --with-fhs Use FHS-compliant paths (default=no)], + libdir="\${prefix}/lib/samba", + libdir="\${prefix}/lib") + +AC_SUBST(libdir) + +SAMBA_SOURCE="../../source" +#################################################### +# set the location location of the samba source tree +AC_ARG_WITH(samba-source, +[ --with-samba-source=DIR Where is the samba source tree (../../source)], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-samba-source called without argument - will use default]) + ;; + * ) + SAMBA_SOURCE="$withval" + ;; + esac]) + +AC_SUBST(SAMBA_SOURCE) + +dnl Unique-to-Samba variables we'll be playing with. +AC_SUBST(CC) +AC_SUBST(SHELL) +AC_SUBST(LDSHFLAGS) +AC_SUBST(SONAMEFLAG) +AC_SUBST(SHLD) +AC_SUBST(HOST_OS) +AC_SUBST(PICFLAGS) +AC_SUBST(PICSUFFIX) +AC_SUBST(SHLIBEXT) +AC_SUBST(INSTALLCLIENTCMD_SH) +AC_SUBST(INSTALLCLIENTCMD_A) +AC_SUBST(SHLIB_PROGS) +AC_SUBST(EXTRA_BIN_PROGS) +AC_SUBST(EXTRA_SBIN_PROGS) +AC_SUBST(EXTRA_ALL_TARGETS) + +AC_ARG_ENABLE(debug, +[ --enable-debug Turn on compiler debugging information (default=no)], + [if eval "test x$enable_debug = xyes"; then + CFLAGS="${CFLAGS} -g" + fi]) + +AC_ARG_ENABLE(developer, [ --enable-developer Turn on developer warnings and debugging (default=no)], + [if eval "test x$enable_developer = xyes"; then + developer=yes + CFLAGS="${CFLAGS} -g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER" + fi]) + +# compile with optimization and without debugging by default, but +# allow people to set their own preference. +if test "x$CFLAGS" = x +then + CFLAGS="-O ${CFLAGS}" +fi + + ################################################# + # check for krb5-config from recent MIT and Heimdal kerberos 5 + AC_PATH_PROG(KRB5CONFIG, krb5-config) + AC_MSG_CHECKING(for working krb5-config) + if test -x "$KRB5CONFIG"; then + CFLAGS="$CFLAGS `$KRB5CONFIG --cflags | sed s/@INCLUDE_des@//`" + CPPFLAGS="$CPPFLAGS `$KRB5CONFIG --cflags | sed s/@INCLUDE_des@//`" + FOUND_KRB5=yes + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no. Fallback to previous krb5 detection strategy) + fi + + if test x$FOUND_KRB5 = x"no"; then + ################################################# + # check for location of Kerberos 5 install + AC_MSG_CHECKING(for kerberos 5 install path) + AC_ARG_WITH(krb5, + [ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)], + [ case "$withval" in + no) + AC_MSG_RESULT(no) + ;; + *) + AC_MSG_RESULT(yes) + CFLAGS="$CFLAGS -I$withval/include" + CPPFLAGS="$CPPFLAGS -I$withval/include" + FOUND_KRB5=yes + ;; + esac ], + AC_MSG_RESULT(no) + ) + fi + +if test x$FOUND_KRB5 = x"no"; then +################################################# +# see if this box has the SuSE location for the heimdal kerberos implementation +AC_MSG_CHECKING(for /usr/include/heimdal) +if test -d /usr/include/heimdal; then + if test -f /usr/lib/heimdal/lib/libkrb5.a; then + CFLAGS="$CFLAGS -I/usr/include/heimdal" + CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal" + AC_MSG_RESULT(yes) + else + CFLAGS="$CFLAGS -I/usr/include/heimdal" + CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal" + AC_MSG_RESULT(yes) + + fi +else + AC_MSG_RESULT(no) +fi +fi + + +if test x$FOUND_KRB5 = x"no"; then +################################################# +# see if this box has the RedHat location for kerberos +AC_MSG_CHECKING(for /usr/kerberos) +if test -d /usr/kerberos -a -f /usr/kerberos/lib/libkrb5.a; then + LDFLAGS="$LDFLAGS -L/usr/kerberos/lib" + CFLAGS="$CFLAGS -I/usr/kerberos/include" + CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include" + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi +fi + + # now check for krb5.h. Some systems have the libraries without the headers! + # note that this check is done here to allow for different kerberos + # include paths + AC_CHECK_HEADERS(krb5.h) + + # now check for gssapi headers. This is also done here to allow for + # different kerberos include paths + AC_CHECK_HEADERS(gssapi.h gssapi/gssapi_generic.h gssapi/gssapi.h com_err.h) + +#dnl Check if we use GNU ld +#LD=ld +#AC_PROG_LD_GNU + +#dnl look for executable suffix +#AC_EXEEXT + +builddir=`pwd` +AC_SUBST(builddir) + +# Assume non-shared by default and override below +BLDSHARED="false" + +# these are the defaults, good for lots of systems +HOST_OS="$host_os" +LDSHFLAGS="-shared" +SONAMEFLAG="#" +SHLD="\${CC}" +PICFLAGS="" +PICSUFFIX="po" +SHLIBEXT="so" + +# Since we are not embedded in the Samba tree, building shared modules is +# really the only option. +enable_shared=yes + +if test "$enable_shared" = "yes"; then + # this bit needs to be modified for each OS that is suported by + # smbwrapper. You need to specify how to created a shared library and + # how to compile C code to produce PIC object files + + AC_MSG_CHECKING([ability to build shared libraries]) + + # and these are for particular systems + case "$host_os" in + *linux*) + BLDSHARED="true" + LDSHFLAGS="-shared" + DYNEXP="-Wl,--export-dynamic" + PICFLAGS="-fPIC" + SONAMEFLAG="-Wl,-soname=" + ;; + *solaris*) + BLDSHARED="true" + LDSHFLAGS="-G" + SONAMEFLAG="-h " + if test "${GCC}" = "yes"; then + PICFLAGS="-fPIC" + if test "${ac_cv_prog_gnu_ld}" = "yes"; then + DYNEXP="-Wl,-E" + fi + else + PICFLAGS="-KPIC" + ## ${CFLAGS} added for building 64-bit shared + ## libs using Sun's Compiler + LDSHFLAGS="-G \${CFLAGS}" + PICSUFFIX="po.o" + fi + ;; + *sunos*) + BLDSHARED="true" + LDSHFLAGS="-G" + SONAMEFLAG="-Wl,-h," + PICFLAGS="-KPIC" # Is this correct for SunOS + ;; + *netbsd* | *freebsd*) BLDSHARED="true" + LDSHFLAGS="-shared" + DYNEXP="-Wl,--export-dynamic" + SONAMEFLAG="-Wl,-soname," + PICFLAGS="-fPIC -DPIC" + ;; + *openbsd*) BLDSHARED="true" + LDSHFLAGS="-shared" + DYNEXP="-Wl,-Bdynamic" + SONAMEFLAG="-Wl,-soname," + PICFLAGS="-fPIC" + ;; + *irix*) + case "$host_os" in + *irix6*) + ;; + esac + ATTEMPT_WRAP32_BUILD=yes + BLDSHARED="true" + LDSHFLAGS="-set_version sgi1.0 -shared" + SONAMEFLAG="-soname " + SHLD="\${LD}" + if test "${GCC}" = "yes"; then + PICFLAGS="-fPIC" + else + PICFLAGS="-KPIC" + fi + ;; + *aix*) + BLDSHARED="true" + LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-bnoentry,-berok" + DYNEXP="-Wl,-brtl,-bexpall" + PICFLAGS="-O2" + if test "${GCC}" != "yes"; then + ## for funky AIX compiler using strncpy() + CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000" + fi + ;; + *hpux*) + SHLIBEXT="sl" + # Use special PIC flags for the native HP-UX compiler. + if test $ac_cv_prog_cc_Ae = yes; then + BLDSHARED="true" + SHLD="/usr/bin/ld" + LDSHFLAGS="-B symbolic -b -z" + SONAMEFLAG="+h " + PICFLAGS="+z" + fi + DYNEXP="-Wl,-E" + ;; + *qnx*) + ;; + *osf*) + BLDSHARED="true" + LDSHFLAGS="-shared" + SONAMEFLAG="-Wl,-soname," + PICFLAGS="-fPIC" + ;; + *sco*) + ;; + *unixware*) + BLDSHARED="true" + LDSHFLAGS="-shared" + SONAMEFLAG="-Wl,-soname," + PICFLAGS="-KPIC" + ;; + *next2*) + ;; + *dgux*) AC_CHECK_PROG( ROFF, groff, [groff -etpsR -Tascii -man]) + ;; + *sysv4*) + case "$host" in + *-univel-*) + LDSHFLAGS="-G" + DYNEXP="-Bexport" + ;; + *mips-sni-sysv4*) + ;; + esac + ;; + + *sysv5*) + LDSHFLAGS="-G" + ;; + *vos*) + BLDSHARED="false" + LDSHFLAGS="" + ;; + *darwin*) + BLDSHARED="true" + LDSHFLAGS="-bundle -flat_namespace -undefined suppress" + SHLIBEXT="dylib" + ;; + *) + ;; + esac + AC_SUBST(DYNEXP) + AC_MSG_RESULT($BLDSHARED) + AC_MSG_CHECKING([linker flags for shared libraries]) + AC_MSG_RESULT([$LDSHFLAGS]) + AC_MSG_CHECKING([compiler flags for position-independent code]) + AC_MSG_RESULT([$PICFLAGS]) +fi + +####################################################### +# test whether building a shared library actually works +if test $BLDSHARED = true; then +AC_CACHE_CHECK([whether building shared libraries actually works], + [ac_cv_shlib_works],[ + ac_cv_shlib_works=no + # try building a trivial shared library + if test "$PICSUFFIX" = "po"; then + $CC $CPPFLAGS $CFLAGS $PICFLAGS -c -o shlib.po ${srcdir-.}/../../source/tests/shlib.c && + $CC $CPPFLAGS $CFLAGS `eval echo $LDSHFLAGS` -o "shlib.$SHLIBEXT" shlib.po && + ac_cv_shlib_works=yes + else + $CC $CPPFLAGS $CFLAGS $PICFLAGS -c -o shlib.$PICSUFFIX ${srcdir-.}/tests/shlib.c && + mv shlib.$PICSUFFIX shlib.po && + $CC $CPPFLAGS $CFLAGS `eval echo $LDSHFLAGS` -o "shlib.$SHLIBEXT" shlib.po && + ac_cv_shlib_works=yes + fi + rm -f "shlib.$SHLIBEXT" shlib.po +]) +if test $ac_cv_shlib_works = no; then + BLDSHARED=false +fi +fi + + + + +AC_OUTPUT(Makefile) diff --git a/examples/VFS/install-sh b/examples/VFS/install-sh new file mode 100644 index 0000000000..58719246f0 --- /dev/null +++ b/examples/VFS/install-sh @@ -0,0 +1,238 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/examples/VFS/shadow_copy_test.c b/examples/VFS/shadow_copy_test.c new file mode 100644 index 0000000000..1ba46b7176 --- /dev/null +++ b/examples/VFS/shadow_copy_test.c @@ -0,0 +1,86 @@ +/* + * TEST implementation of an Shadow Copy module + * + * Copyright (C) Stefan Metzmacher 2003 + * + * 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/>. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS + +/* USE THIS MODULE ONLY FOR TESTING!!!! */ + +/* + For this share + Z:\ + + the ShadowCopies are in this directories + + Z:\@GMT-2003.08.05-12.00.00\ + Z:\@GMT-2003.08.05-12.01.00\ + Z:\@GMT-2003.08.05-12.02.00\ + + e.g. + + Z:\testfile.txt + Z:\@GMT-2003.08.05-12.02.00\testfile.txt + + or: + + Z:\testdir\testfile.txt + Z:\@GMT-2003.08.05-12.02.00\testdir\testfile.txt + + + Note: Files must differ to be displayed via Windows Explorer! + Directories are always displayed... +*/ + +static int test_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels) +{ + uint32 num = 3; + uint32 i; + + shadow_copy_data->num_volumes = num; + + if (labels) { + if (num) { + shadow_copy_data->labels = TALLOC_ZERO_ARRAY(shadow_copy_data->mem_ctx,SHADOW_COPY_LABEL,num); + } else { + shadow_copy_data->labels = NULL; + } + for (i=0;i<num;i++) { + snprintf(shadow_copy_data->labels[i], sizeof(SHADOW_COPY_LABEL), "@GMT-2003.08.05-12.%02u.00",i); + } + } else { + shadow_copy_data->labels = NULL; + } + + return 0; +} + +/* VFS operations structure */ + +static vfs_op_tuple shadow_copy_test_ops[] = { + {SMB_VFS_OP(test_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_OPAQUE}, + + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS init_module(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy_test", shadow_copy_test_ops); +} diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c new file mode 100644 index 0000000000..89d8ce5239 --- /dev/null +++ b/examples/VFS/skel_opaque.c @@ -0,0 +1,721 @@ +/* + * Skeleton VFS module. Implements passthrough operation of all VFS + * calls to disk functions. + * + * Copyright (C) Tim Potter, 1999-2000 + * Copyright (C) Alexander Bokovoy, 2002 + * Copyright (C) Stefan (metze) Metzmacher, 2003 + * + * 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/>. + */ + + +#include "includes.h" + +/* PLEASE,PLEASE READ THE VFS MODULES CHAPTER OF THE + SAMBA DEVELOPERS GUIDE!!!!!! + */ + +/* If you take this file as template for your module + * please make sure that you remove all vfswrap_* functions and + * implement your own function!! + * + * for functions you didn't want to provide implement dummy functions + * witch return ERROR and errno = ENOSYS; ! + * + * --metze + */ + +/* NOTE: As of approximately Samba 3.0.24, the vfswrap_* functions are not + * global symbols. They are included here only as an pointer that opaque + * operations should not call further into the VFS. + */ + +static int skel_connect(vfs_handle_struct *handle, const char *service, const char *user) +{ + return 0; +} + +static void skel_disconnect(vfs_handle_struct *handle, connection_struct *conn) +{ + return; +} + +static SMB_BIG_UINT skel_disk_free(vfs_handle_struct *handle, const char *path, + bool small_query, SMB_BIG_UINT *bsize, + SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +{ + return vfswrap_disk_free(NULL, path, small_query, bsize, + dfree, dsize); +} + +static int skel_get_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq) +{ + return vfswrap_get_quota(NULL, qtype, id, dq); +} + +static int skel_set_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq) +{ + return vfswrap_set_quota(NULL, qtype, id, dq); +} + +static int skel_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels) +{ + return vfswrap_get_shadow_copy_data(NULL, fsp, shadow_copy_data, labels); +} + +static int skel_statvfs(struct vfs_handle_struct *handle, const char *path, struct vfs_statvfs_struct *statbuf) +{ + return vfswrap_statvfs(NULL, path, statbuf); +} + +static SMB_STRUCT_DIR *skel_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) +{ + return vfswrap_opendir(NULL, fname, mask, attr); +} + +static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + return vfswrap_readdir(NULL, dirp); +} + +static void skel_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset) +{ + vfswrap_seekdir(NULL, dirp, offset); +} + +static long skel_telldir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + return vfswrap_telldir(NULL, dirp); +} + +static void skel_rewinddir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + vfswrap_rewinddir(NULL, dirp); +} + +static int skel_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) +{ + return vfswrap_mkdir(NULL, path, mode); +} + +static int skel_rmdir(vfs_handle_struct *handle, const char *path) +{ + return vfswrap_rmdir(NULL, path); +} + +static int skel_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dir) +{ + return vfswrap_closedir(NULL, dir); +} + +static int skel_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode) +{ + return vfswrap_open(NULL, fname, flags, mode); +} + +static int skel_close(vfs_handle_struct *handle, files_struct *fsp) +{ + return vfswrap_close(NULL, fsp); +} + +static ssize_t skel_read(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n) +{ + return vfswrap_read(NULL, fsp, data, n); +} + +static ssize_t skel_pread(vfs_handle_struct *handle, struct files_struct *fsp, void *data, size_t n, SMB_OFF_T offset) +{ + return vfswrap_pread(NULL, fsp, data, n, offset); +} + +static ssize_t skel_write(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n) +{ + return vfswrap_write(NULL, fsp, data, n); +} + +ssize_t skel_pwrite(vfs_handle_struct *handle, struct files_struct *fsp, const void *data, size_t n, SMB_OFF_T offset) +{ + return vfswrap_pwrite(NULL, fsp, data, n, offset); +} + +static SMB_OFF_T skel_lseek(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset, int whence) +{ + return vfswrap_lseek(NULL, fsp, offset, whence); +} + +static ssize_t skel_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fromfsp, const DATA_BLOB *hdr, + SMB_OFF_T offset, size_t n) +{ + return vfswrap_sendfile(NULL, tofd, fromfsp, hdr, offset, n); +} + +static ssize_t skel_recvfile(vfs_handle_struct *handle, int fromfd, files_struct *tofsp, SMB_OFF_T offset, size_t n) +{ + return vfswrap_recvfile(NULL, fromfd, tofsp, offset, n); +} + +static int skel_rename(vfs_handle_struct *handle, const char *oldname, const char *newname) +{ + return vfswrap_rename(NULL, oldname, newname); +} + +static int skel_fsync(vfs_handle_struct *handle, files_struct *fsp) +{ + return vfswrap_fsync(NULL, fsp); +} + +static int skel_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf) +{ + return vfswrap_stat(NULL, fname, sbuf); +} + +static int skel_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf) +{ + return vfswrap_fstat(NULL, fsp, sbuf); +} + +static int skel_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf) +{ + return vfswrap_lstat(NULL, path, sbuf); +} + +static int skel_unlink(vfs_handle_struct *handle, const char *path) +{ + return vfswrap_unlink(NULL, path); +} + +static int skel_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) +{ + return vfswrap_chmod(NULL, path, mode); +} + +static int skel_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode) +{ + return vfswrap_fchmod(NULL, fsp, mode); +} + +static int skel_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) +{ + return vfswrap_chown(NULL, path, uid, gid); +} + +static int skel_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid) +{ + return vfswrap_fchown(NULL, fsp, uid, gid); +} + +static int skel_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) +{ + return vfswrap_lchown(NULL, path, uid, gid); +} + +static int skel_chdir(vfs_handle_struct *handle, const char *path) +{ + return vfswrap_chdir(NULL, path); +} + +static char *skel_getwd(vfs_handle_struct *handle, char *buf) +{ + return vfswrap_getwd(NULL, buf); +} + +static int skel_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2]) +{ + return vfswrap_ntimes(NULL, path, ts); +} + +static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset) +{ + return vfswrap_ftruncate(NULL, fsp, offset); +} + +static bool skel_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) +{ + return vfswrap_lock(NULL, fsp, op, offset, count, type); +} + +static bool skel_getlock(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid) +{ + return vfswrap_getlock(NULL, fsp, poffset, pcount, ptype, ppid); +} + +static int skel_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath) +{ + return vfswrap_symlink(NULL, oldpath, newpath); +} + + +static int skel_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz) +{ + return vfswrap_readlink(NULL, path, buf, bufsiz); +} + +static int skel_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath) +{ + return vfswrap_link(NULL, oldpath, newpath); +} + +static int skel_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev) +{ + return vfswrap_mknod(NULL, path, mode, dev); +} + +static char *skel_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path) +{ + return vfswrap_realpath(NULL, path, resolved_path); +} + +static NTSTATUS skel_notify_watch(struct vfs_handle_struct *handle, + struct sys_notify_context *ctx, struct notify_entry *e, + void (*callback)(struct sys_notify_context *ctx, void *private_data, struct notify_event *ev), + void *private_data, void *handle_p) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +static int skel_chflags(vfs_handle_struct *handle, const char *path, uint flags) +{ + errno = ENOSYS; + return -1; +} + +static struct file_id skel_file_id_create(vfs_handle_struct *handle, + SMB_DEV_T dev, SMB_INO_T inode) +{ + struct file_id id_zero; + ZERO_STRUCT(id_zero); + errno = ENOSYS; + return id_zero; +} + +static size_t skel_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, + uint32 security_info, SEC_DESC **ppdesc) +{ + errno = ENOSYS; + return 0; +} + +static size_t skel_get_nt_acl(vfs_handle_struct *handle, + const char *name, uint32 security_info, SEC_DESC **ppdesc) +{ + errno = ENOSYS; + return 0; +} + +static NTSTATUS skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, + uint32 security_info_sent, SEC_DESC *psd) +{ + errno = ENOSYS; + return NT_STATUS_NOT_IMPLEMENTED; +} + +static int skel_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode) +{ + errno = ENOSYS; + return -1; +} + +static int skel_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_get_entry(vfs_handle_struct *handle, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_get_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_get_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) +{ + errno = ENOSYS; + return -1; +} + +static void *skel_sys_acl_get_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d) +{ + errno = ENOSYS; + return NULL; +} + +static SMB_ACL_T skel_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type) +{ + errno = ENOSYS; + return NULL; +} + +static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) +{ + errno = ENOSYS; + return NULL; +} + +static int skel_sys_acl_clear_perms(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_add_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) +{ + errno = ENOSYS; + return -1; +} + +static char *skel_sys_acl_to_text(vfs_handle_struct *handle, SMB_ACL_T theacl, ssize_t *plen) +{ + errno = ENOSYS; + return NULL; +} + +static SMB_ACL_T skel_sys_acl_init(vfs_handle_struct *handle, int count) +{ + errno = ENOSYS; + return NULL; +} + +static int skel_sys_acl_create_entry(vfs_handle_struct *handle, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_set_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_set_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, void *qual) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_set_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_valid(vfs_handle_struct *handle, SMB_ACL_T theacl ) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_get_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_free_text(vfs_handle_struct *handle, char *text) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_free_acl(vfs_handle_struct *handle, SMB_ACL_T posix_acl) +{ + errno = ENOSYS; + return -1; +} + +static int skel_sys_acl_free_qualifier(vfs_handle_struct *handle, void *qualifier, SMB_ACL_TAG_T tagtype) +{ + errno = ENOSYS; + return -1; +} + +static ssize_t skel_getxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t size) +{ + errno = ENOSYS; + return -1; +} + +static ssize_t skel_lgetxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t +size) +{ + errno = ENOSYS; + return -1; +} + +static ssize_t skel_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size) +{ + errno = ENOSYS; + return -1; +} + +static ssize_t skel_listxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size) +{ + errno = ENOSYS; + return -1; +} + +static ssize_t skel_llistxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size) +{ + errno = ENOSYS; + return -1; +} + +static ssize_t skel_flistxattr(vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size) +{ + errno = ENOSYS; + return -1; +} + +static int skel_removexattr(vfs_handle_struct *handle, const char *path, const char *name) +{ + errno = ENOSYS; + return -1; +} + +static int skel_lremovexattr(vfs_handle_struct *handle, const char *path, const char *name) +{ + errno = ENOSYS; + return -1; +} + +static int skel_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *name) +{ + errno = ENOSYS; + return -1; +} + +static int skel_setxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags) +{ + errno = ENOSYS; + return -1; +} + +static int skel_lsetxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags) +{ + errno = ENOSYS; + return -1; +} + +static int skel_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags) +{ + errno = ENOSYS; + return -1; +} + +static int skel_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_read(NULL, fsp, aiocb); +} + +static int skel_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_write(NULL, fsp, aiocb); +} + +static ssize_t skel_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_return(NULL, fsp, aiocb); +} + +static int skel_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_cancel(NULL, fsp, aiocb); +} + +static int skel_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_error(NULL, fsp, aiocb); +} + +static int skel_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb) +{ + return vfswrap_aio_fsync(NULL, fsp, op, aiocb); +} + +static int skel_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *ts) +{ + return vfswrap_aio_suspend(NULL, fsp, aiocb, n, ts); +} + +static bool skel_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp) +{ + return vfswrap_aio_force(NULL, fsp); +} + +static bool skel_is_offline(struct vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf) +{ + return vfswrap_is_offline(NULL, path, sbuf); +} + +static int skel_set_offline(struct vfs_handle_struct *handle, const char *path) +{ + return vfswrap_set_offline(NULL, path); +} + +/* VFS operations structure */ + +static vfs_op_tuple skel_op_tuples[] = { + + /* Disk operations */ + + {SMB_VFS_OP(skel_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_disk_free), SMB_VFS_OP_DISK_FREE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_get_quota), SMB_VFS_OP_GET_QUOTA, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_set_quota), SMB_VFS_OP_SET_QUOTA, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_statvfs), SMB_VFS_OP_STATVFS, SMB_VFS_LAYER_OPAQUE}, + + /* Directory operations */ + + {SMB_VFS_OP(skel_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_seekdir), SMB_VFS_OP_SEEKDIR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_telldir), SMB_VFS_OP_TELLDIR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_rewinddir), SMB_VFS_OP_REWINDDIR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_OPAQUE}, + + /* File operations */ + + {SMB_VFS_OP(skel_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_read), SMB_VFS_OP_READ, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_pread), SMB_VFS_OP_PREAD, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_write), SMB_VFS_OP_WRITE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_pwrite), SMB_VFS_OP_PWRITE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_lseek), SMB_VFS_OP_LSEEK, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sendfile), SMB_VFS_OP_SENDFILE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_recvfile), SMB_VFS_OP_RECVFILE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_fsync), SMB_VFS_OP_FSYNC, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_fchown), SMB_VFS_OP_FCHOWN, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_lchown), SMB_VFS_OP_LCHOWN, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_getwd), SMB_VFS_OP_GETWD, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_ntimes), SMB_VFS_OP_NTIMES, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_ftruncate), SMB_VFS_OP_FTRUNCATE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_lock), SMB_VFS_OP_LOCK, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_getlock), SMB_VFS_OP_GETLOCK, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_symlink), SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_readlink), SMB_VFS_OP_READLINK, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_link), SMB_VFS_OP_LINK, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_mknod), SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_realpath), SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_notify_watch), SMB_VFS_OP_NOTIFY_WATCH, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_chflags), SMB_VFS_OP_CHFLAGS, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_file_id_create), SMB_VFS_OP_FILE_ID_CREATE, SMB_VFS_LAYER_OPAQUE}, + + /* NT File ACL operations */ + + {SMB_VFS_OP(skel_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL, SMB_VFS_LAYER_OPAQUE}, + + /* POSIX ACL operations */ + + {SMB_VFS_OP(skel_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_OPAQUE}, + + {SMB_VFS_OP(skel_sys_acl_get_entry), SMB_VFS_OP_SYS_ACL_GET_ENTRY, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_get_tag_type), SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_get_permset), SMB_VFS_OP_SYS_ACL_GET_PERMSET, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_get_qualifier), SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_get_fd), SMB_VFS_OP_SYS_ACL_GET_FD, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_clear_perms), SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_add_perm), SMB_VFS_OP_SYS_ACL_ADD_PERM, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_to_text), SMB_VFS_OP_SYS_ACL_TO_TEXT, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_init), SMB_VFS_OP_SYS_ACL_INIT, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_create_entry), SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_set_tag_type), SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_set_qualifier), SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_set_permset), SMB_VFS_OP_SYS_ACL_SET_PERMSET, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_valid), SMB_VFS_OP_SYS_ACL_VALID, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_set_fd), SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_delete_def_file), SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_get_perm), SMB_VFS_OP_SYS_ACL_GET_PERM, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_free_text), SMB_VFS_OP_SYS_ACL_FREE_TEXT, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_free_acl), SMB_VFS_OP_SYS_ACL_FREE_ACL, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_sys_acl_free_qualifier), SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, SMB_VFS_LAYER_OPAQUE}, + + /* EA operations. */ + {SMB_VFS_OP(skel_getxattr), SMB_VFS_OP_GETXATTR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_lgetxattr), SMB_VFS_OP_LGETXATTR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_fgetxattr), SMB_VFS_OP_FGETXATTR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_listxattr), SMB_VFS_OP_LISTXATTR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_llistxattr), SMB_VFS_OP_LLISTXATTR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_flistxattr), SMB_VFS_OP_FLISTXATTR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_removexattr), SMB_VFS_OP_REMOVEXATTR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_lremovexattr), SMB_VFS_OP_LREMOVEXATTR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_fremovexattr), SMB_VFS_OP_FREMOVEXATTR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_setxattr), SMB_VFS_OP_SETXATTR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_lsetxattr), SMB_VFS_OP_LSETXATTR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_fsetxattr), SMB_VFS_OP_FSETXATTR, SMB_VFS_LAYER_OPAQUE}, + + /* AIO operations. */ + {SMB_VFS_OP(skel_aio_read), SMB_VFS_OP_AIO_READ, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_write), SMB_VFS_OP_AIO_WRITE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_return), SMB_VFS_OP_AIO_RETURN, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_cancel), SMB_VFS_OP_AIO_CANCEL, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_error), SMB_VFS_OP_AIO_ERROR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_fsync), SMB_VFS_OP_AIO_FSYNC, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_suspend), SMB_VFS_OP_AIO_SUSPEND, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_aio_force), SMB_VFS_OP_AIO_FORCE, SMB_VFS_LAYER_OPAQUE}, + + /* offline operations */ + {SMB_VFS_OP(skel_is_offline), SMB_VFS_OP_IS_OFFLINE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_set_offline), SMB_VFS_OP_SET_OFFLINE, SMB_VFS_LAYER_OPAQUE}, + + {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS init_module(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "skel_opaque", skel_op_tuples); +} diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c new file mode 100644 index 0000000000..ea8530d855 --- /dev/null +++ b/examples/VFS/skel_transparent.c @@ -0,0 +1,684 @@ +/* + * Skeleton VFS module. Implements passthrough operation of all VFS + * calls to disk functions. + * + * Copyright (C) Tim Potter, 1999-2000 + * Copyright (C) Alexander Bokovoy, 2002 + * Copyright (C) Stefan (metze) Metzmacher, 2003 + * + * 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/>. + */ + + +#include "includes.h" + +/* PLEASE,PLEASE READ THE VFS MODULES CHAPTER OF THE + SAMBA DEVELOPERS GUIDE!!!!!! + */ + +/* If you take this file as template for your module + * please make sure that you remove all functions you didn't + * want to implement!! + * + * This passthrough operations are useless in reall vfs modules! + * + * --metze + */ + +static int skel_connect(vfs_handle_struct *handle, const char *service, const char *user) +{ + return SMB_VFS_NEXT_CONNECT(handle, service, user); +} + +static void skel_disconnect(vfs_handle_struct *handle) +{ + SMB_VFS_NEXT_DISCONNECT(handle); +} + +static SMB_BIG_UINT skel_disk_free(vfs_handle_struct *handle, const char *path, + bool small_query, SMB_BIG_UINT *bsize, + SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +{ + return SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, bsize, + dfree, dsize); +} + +static int skel_get_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq) +{ + return SMB_VFS_NEXT_GET_QUOTA(handle, qtype, id, dq); +} + +static int skel_set_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq) +{ + return SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, dq); +} + +static int skel_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels) +{ + return SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data, labels); +} + +static int skel_statvfs(struct vfs_handle_struct *handle, const char *path, struct vfs_statvfs_struct *statbuf) +{ + return SMB_VFS_NEXT_STATVFS(handle, path, statbuf); +} + +static SMB_STRUCT_DIR *skel_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) +{ + return SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); +} + +static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + return SMB_VFS_NEXT_READDIR(handle, dirp); +} + +static void skel_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset) +{ + return SMB_VFS_NEXT_SEEKDIR(handle, dirp, offset); +} + +static long skel_telldir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + return SMB_VFS_NEXT_TELLDIR(handle, dirp); +} + +static void skel_rewinddir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + return SMB_VFS_NEXT_REWINDDIR(handle, dirp); +} + +static int skel_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) +{ + return SMB_VFS_NEXT_MKDIR(handle, path, mode); +} + +static int skel_rmdir(vfs_handle_struct *handle, const char *path) +{ + return SMB_VFS_NEXT_RMDIR(handle, path); +} + +static int skel_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dir) +{ + return SMB_VFS_NEXT_CLOSEDIR(handle, dir); +} + +static int skel_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode) +{ + return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); +} + +static int skel_close(vfs_handle_struct *handle, files_struct *fsp) +{ + return SMB_VFS_NEXT_CLOSE(handle, fsp); +} + +static ssize_t skel_read(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n) +{ + return SMB_VFS_NEXT_READ(handle, fsp, data, n); +} + +static ssize_t skel_pread(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n, SMB_OFF_T offset) +{ + return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset); +} + +static ssize_t skel_write(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n) +{ + return SMB_VFS_NEXT_WRITE(handle, fsp, data, n); +} + +static ssize_t skel_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n, SMB_OFF_T offset) +{ + return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); +} + +static SMB_OFF_T skel_lseek(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset, int whence) +{ + return SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence); +} + +static ssize_t skel_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fromfsp, const DATA_BLOB *hdr, SMB_OFF_T offset, size_t n) +{ + return SMB_VFS_NEXT_SENDFILE(handle, tofd, fromfsp, hdr, offset, n); +} + +static ssize_t skel_recvfile(vfs_handle_struct *handle, int fromfd, files_struct *tofsp, SMB_OFF_T offset, size_t n) +{ + return SMB_VFS_NEXT_RECVFILE(handle, fromfd, tofsp, offset, n); +} + +static int skel_rename(vfs_handle_struct *handle, const char *oldname, const char *newname) +{ + return SMB_VFS_NEXT_RENAME(handle, oldname, newname); +} + +static int skel_fsync(vfs_handle_struct *handle, files_struct *fsp) +{ + return SMB_VFS_NEXT_FSYNC(handle, fsp); +} + +static int skel_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf) +{ + return SMB_VFS_NEXT_STAT(handle, fname, sbuf); +} + +static int skel_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf) +{ + return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); +} + +static int skel_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf) +{ + return SMB_VFS_NEXT_LSTAT(handle, path, sbuf); +} + +static int skel_unlink(vfs_handle_struct *handle, const char *path) +{ + return SMB_VFS_NEXT_UNLINK(handle, path); +} + +static int skel_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) +{ + return SMB_VFS_NEXT_CHMOD(handle, path, mode); +} + +static int skel_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode) +{ + return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); +} + +static int skel_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) +{ + return SMB_VFS_NEXT_CHOWN(handle, path, uid, gid); +} + +static int skel_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid) +{ + return SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid); +} + +static int skel_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) +{ + return SMB_VFS_NEXT_LCHOWN(handle, path, uid, gid); +} + +static int skel_chdir(vfs_handle_struct *handle, const char *path) +{ + return SMB_VFS_NEXT_CHDIR(handle, path); +} + +static char *skel_getwd(vfs_handle_struct *handle, char *buf) +{ + return SMB_VFS_NEXT_GETWD(handle, buf); +} + +static int skel_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2]) +{ + return SMB_VFS_NEXT_NTIMES(handle, path, ts); +} + +static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset) +{ + return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset); +} + +static bool skel_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) +{ + return SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type); +} + +static bool skel_getlock(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid) +{ + return SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid); +} + +static int skel_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath) +{ + return SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath); +} + +static int skel_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz) +{ + return SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz); +} + +static int skel_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath) +{ + return SMB_VFS_NEXT_LINK(handle, oldpath, newpath); +} + +static int skel_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev) +{ + return SMB_VFS_NEXT_MKNOD(handle, path, mode, dev); +} + +static char *skel_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path) +{ + return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path); +} + +static NTSTATUS skel_notify_watch(struct vfs_handle_struct *handle, + struct sys_notify_context *ctx, struct notify_entry *e, + void (*callback)(struct sys_notify_context *ctx, void *private_data, struct notify_event *ev), + void *private_data, void *handle_p) +{ + return SMB_VFS_NEXT_NOTIFY_WATCH(handle, ctx, e, callback, + private_data, handle_p); +} + +static int skel_chflags(vfs_handle_struct *handle, const char *path, uint flags) +{ + return SMB_VFS_NEXT_CHFLAGS(handle, path, flags); +} + +static struct file_id skel_file_id_create(vfs_handle_struct *handle, + SMB_DEV_T dev, SMB_INO_T inode) +{ + return SMB_VFS_NEXT_FILE_ID_CREATE(handle, dev, inode); +} + +static NTSTATUS skel_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, + uint32 security_info, SEC_DESC **ppdesc) +{ + return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); +} + +static NTSTATUS skel_get_nt_acl(vfs_handle_struct *handle, + const char *name, uint32 security_info, SEC_DESC **ppdesc) +{ + return SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, ppdesc); +} + +static NTSTATUS skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, + uint32 security_info_sent, SEC_DESC *psd) +{ + return SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); +} + +static int skel_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode) +{ + /* If the underlying VFS doesn't have ACL support... */ + if (!handle->vfs_next.ops.chmod_acl) { + errno = ENOSYS; + return -1; + } + return SMB_VFS_NEXT_CHMOD_ACL(handle, name, mode); +} + +static int skel_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode) +{ + /* If the underlying VFS doesn't have ACL support... */ + if (!handle->vfs_next.ops.fchmod_acl) { + errno = ENOSYS; + return -1; + } + return SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode); +} + +static int skel_sys_acl_get_entry(vfs_handle_struct *handle, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) +{ + return SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, theacl, entry_id, entry_p); +} + +static int skel_sys_acl_get_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) +{ + return SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, entry_d, tag_type_p); +} + +static int skel_sys_acl_get_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) +{ + return SMB_VFS_NEXT_SYS_ACL_GET_PERMSET(handle, entry_d, permset_p); +} + +static void *skel_sys_acl_get_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d) +{ + return SMB_VFS_NEXT_SYS_ACL_GET_QUALIFIER(handle, entry_d); +} + +static SMB_ACL_T skel_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type) +{ + return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type); +} + +static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) +{ + return SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp); +} + +static int skel_sys_acl_clear_perms(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset) +{ + return SMB_VFS_NEXT_SYS_ACL_CLEAR_PERMS(handle, permset); +} + +static int skel_sys_acl_add_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) +{ + return SMB_VFS_NEXT_SYS_ACL_ADD_PERM(handle, permset, perm); +} + +static char *skel_sys_acl_to_text(vfs_handle_struct *handle, SMB_ACL_T theacl, ssize_t *plen) +{ + return SMB_VFS_NEXT_SYS_ACL_TO_TEXT(handle, theacl, plen); +} + +static SMB_ACL_T skel_sys_acl_init(vfs_handle_struct *handle, int count) +{ + return SMB_VFS_NEXT_SYS_ACL_INIT(handle, count); +} + +static int skel_sys_acl_create_entry(vfs_handle_struct *handle, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) +{ + return SMB_VFS_NEXT_SYS_ACL_CREATE_ENTRY(handle, pacl, pentry); +} + +static int skel_sys_acl_set_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) +{ + return SMB_VFS_NEXT_SYS_ACL_SET_TAG_TYPE(handle, entry, tagtype); +} + +static int skel_sys_acl_set_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, void *qual) +{ + return SMB_VFS_NEXT_SYS_ACL_SET_QUALIFIER(handle, entry, qual); +} + +static int skel_sys_acl_set_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) +{ + return SMB_VFS_NEXT_SYS_ACL_SET_PERMSET(handle, entry, permset); +} + +static int skel_sys_acl_valid(vfs_handle_struct *handle, SMB_ACL_T theacl ) +{ + return SMB_VFS_NEXT_SYS_ACL_VALID(handle, theacl); +} + +static int skel_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) +{ + return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype, theacl); +} + +static int skel_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl) +{ + return SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl); +} + +static int skel_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path) +{ + return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path); +} + +static int skel_sys_acl_get_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) +{ + return SMB_VFS_NEXT_SYS_ACL_GET_PERM(handle, permset, perm); +} + +static int skel_sys_acl_free_text(vfs_handle_struct *handle, char *text) +{ + return SMB_VFS_NEXT_SYS_ACL_FREE_TEXT(handle, text); +} + +static int skel_sys_acl_free_acl(vfs_handle_struct *handle, SMB_ACL_T posix_acl) +{ + return SMB_VFS_NEXT_SYS_ACL_FREE_ACL(handle, posix_acl); +} + +static int skel_sys_acl_free_qualifier(vfs_handle_struct *handle, void *qualifier, SMB_ACL_TAG_T tagtype) +{ + return SMB_VFS_NEXT_SYS_ACL_FREE_QUALIFIER(handle, qualifier, tagtype); +} + +static ssize_t skel_getxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t size) +{ + return SMB_VFS_NEXT_GETXATTR(handle, path, name, value, size); +} + +static ssize_t skel_lgetxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t +size) +{ + return SMB_VFS_NEXT_LGETXATTR(handle, path, name, value, size); +} + +static ssize_t skel_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size) +{ + return SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size); +} + +static ssize_t skel_listxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size) +{ + return SMB_VFS_NEXT_LISTXATTR(handle, path, list, size); +} + +static ssize_t skel_llistxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size) +{ + return SMB_VFS_NEXT_LLISTXATTR(handle, path, list, size); +} + +static ssize_t skel_flistxattr(vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size) +{ + return SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size); +} + +static int skel_removexattr(vfs_handle_struct *handle, const char *path, const char *name) +{ + return SMB_VFS_NEXT_REMOVEXATTR(handle, path, name); +} + +static int skel_lremovexattr(vfs_handle_struct *handle, const char *path, const char *name) +{ + return SMB_VFS_NEXT_LREMOVEXATTR(handle, path, name); +} + +static int skel_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *name) +{ + return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name); +} + +static int skel_setxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags) +{ + return SMB_VFS_NEXT_SETXATTR(handle, path, name, value, size, flags); +} + +static int skel_lsetxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags) +{ + return SMB_VFS_NEXT_LSETXATTR(handle, path, name, value, size, flags); +} + +static int skel_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags) +{ + return SMB_VFS_NEXT_FSETXATTR(handle, fsp, name, value, size, flags); +} + +static int skel_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_READ(handle, fsp, aiocb); +} + +static int skel_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_WRITE(handle, fsp, aiocb); +} + +static ssize_t skel_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_RETURN(handle, fsp, aiocb); +} + +static int skel_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_CANCEL(handle, fsp, aiocb); +} + +static int skel_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_ERROR(handle, fsp, aiocb); +} + +static int skel_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb) +{ + return SMB_VFS_NEXT_AIO_FSYNC(handle, fsp, op, aiocb); +} + +static int skel_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *ts) +{ + return SMB_VFS_NEXT_AIO_SUSPEND(handle, fsp, aiocb, n, ts); +} + +static bool skel_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp) +{ + return SMB_VFS_NEXT_AIO_FORCE(handle, fsp); +} + +static bool skel_is_offline(struct vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf) +{ + return SMB_VFS_NEXT_IS_OFFLINE(handle, path, sbuf); +} + +static int skel_set_offline(struct vfs_handle_struct *handle, const char *path) +{ + return SMB_VFS_NEXT_SET_OFFLINE(handle, path); +} + +static bool skel_is_remotestorage(struct vfs_handle_struct *handle, const char *path) +{ + return SMB_VFS_NEXT_IS_REMOTESTORAGE(handle, path); +} + +/* VFS operations structure */ + +static vfs_op_tuple skel_op_tuples[] = { + + /* Disk operations */ + + {SMB_VFS_OP(skel_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_disk_free), SMB_VFS_OP_DISK_FREE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_get_quota), SMB_VFS_OP_GET_QUOTA, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_set_quota), SMB_VFS_OP_SET_QUOTA, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_statvfs), SMB_VFS_OP_STATVFS, SMB_VFS_LAYER_TRANSPARENT}, + + /* Directory operations */ + + {SMB_VFS_OP(skel_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_seekdir), SMB_VFS_OP_SEEKDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_telldir), SMB_VFS_OP_TELLDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_rewinddir), SMB_VFS_OP_REWINDDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_TRANSPARENT}, + + /* File operations */ + + {SMB_VFS_OP(skel_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_read), SMB_VFS_OP_READ, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_write), SMB_VFS_OP_WRITE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_lseek), SMB_VFS_OP_LSEEK, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sendfile), SMB_VFS_OP_SENDFILE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_recvfile), SMB_VFS_OP_RECVFILE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_fsync), SMB_VFS_OP_FSYNC, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_fchown), SMB_VFS_OP_FCHOWN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_lchown), SMB_VFS_OP_LCHOWN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_getwd), SMB_VFS_OP_GETWD, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_ntimes), SMB_VFS_OP_NTIMES, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_ftruncate), SMB_VFS_OP_FTRUNCATE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_lock), SMB_VFS_OP_LOCK, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_getlock), SMB_VFS_OP_GETLOCK, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_symlink), SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_readlink), SMB_VFS_OP_READLINK, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_link), SMB_VFS_OP_LINK, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_mknod), SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_realpath), SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_notify_watch), SMB_VFS_OP_NOTIFY_WATCH, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_chflags), SMB_VFS_OP_CHFLAGS, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_file_id_create), SMB_VFS_OP_FILE_ID_CREATE, SMB_VFS_LAYER_TRANSPARENT}, + + /* NT File ACL operations */ + + {SMB_VFS_OP(skel_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, + + /* POSIX ACL operations */ + + {SMB_VFS_OP(skel_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(skel_sys_acl_get_entry), SMB_VFS_OP_SYS_ACL_GET_ENTRY, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_get_tag_type), SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_get_permset), SMB_VFS_OP_SYS_ACL_GET_PERMSET, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_get_qualifier), SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_get_fd), SMB_VFS_OP_SYS_ACL_GET_FD, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_clear_perms), SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_add_perm), SMB_VFS_OP_SYS_ACL_ADD_PERM, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_to_text), SMB_VFS_OP_SYS_ACL_TO_TEXT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_init), SMB_VFS_OP_SYS_ACL_INIT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_create_entry), SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_set_tag_type), SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_set_qualifier), SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_set_permset), SMB_VFS_OP_SYS_ACL_SET_PERMSET, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_valid), SMB_VFS_OP_SYS_ACL_VALID, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_set_fd), SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_delete_def_file), SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_get_perm), SMB_VFS_OP_SYS_ACL_GET_PERM, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_free_text), SMB_VFS_OP_SYS_ACL_FREE_TEXT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_free_acl), SMB_VFS_OP_SYS_ACL_FREE_ACL, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_sys_acl_free_qualifier), SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT}, + + /* EA operations. */ + {SMB_VFS_OP(skel_getxattr), SMB_VFS_OP_GETXATTR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_lgetxattr), SMB_VFS_OP_LGETXATTR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_fgetxattr), SMB_VFS_OP_FGETXATTR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_listxattr), SMB_VFS_OP_LISTXATTR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_llistxattr), SMB_VFS_OP_LLISTXATTR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_flistxattr), SMB_VFS_OP_FLISTXATTR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_removexattr), SMB_VFS_OP_REMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_lremovexattr), SMB_VFS_OP_LREMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_fremovexattr), SMB_VFS_OP_FREMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_setxattr), SMB_VFS_OP_SETXATTR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_lsetxattr), SMB_VFS_OP_LSETXATTR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_fsetxattr), SMB_VFS_OP_FSETXATTR, SMB_VFS_LAYER_TRANSPARENT}, + + /* AIO operations. */ + {SMB_VFS_OP(skel_aio_read), SMB_VFS_OP_AIO_READ, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_write), SMB_VFS_OP_AIO_WRITE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_return), SMB_VFS_OP_AIO_RETURN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_cancel), SMB_VFS_OP_AIO_CANCEL, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_error), SMB_VFS_OP_AIO_ERROR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_fsync), SMB_VFS_OP_AIO_FSYNC, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_suspend), SMB_VFS_OP_AIO_SUSPEND, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_aio_force), SMB_VFS_OP_AIO_FORCE, SMB_VFS_LAYER_TRANSPARENT}, + + /* offline operations */ + {SMB_VFS_OP(skel_is_offline), SMB_VFS_OP_IS_OFFLINE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(skel_set_offline), SMB_VFS_OP_SET_OFFLINE, SMB_VFS_LAYER_TRANSPARENT}, + + {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS init_module(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "skel_transparent", skel_op_tuples); +} diff --git a/examples/auth/Makefile b/examples/auth/Makefile new file mode 100644 index 0000000000..d6dbc28f40 --- /dev/null +++ b/examples/auth/Makefile @@ -0,0 +1,31 @@ +# Makefile for samba-pdb examples +# Variables + +CC = gcc +LIBTOOL = libtool + +SAMBA_SRC = ../../source +SAMBA_INCL = ../../source/include +UBIQX_SRC = ../../source/ubiqx +SMBWR_SRC = ../../source/smbwrapper +CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g +AUTH_OBJS = auth_skel.la + +# Default target + +default: $(AUTH_OBJS) + +# Pattern rules + +%.la: %.lo + $(LIBTOOL) --mode=link $(CC) -module -o $@ $< $(LDFLAGS) + +%.lo: %.c + $(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) -c $< + +# Misc targets + +clean: + rm -rf .libs + rm -f core *~ *% *.bak \ + $(AUTH_OBJS) $(AUTH_OBJS:.la=.o) $(AUTH_OBJS:.la=.lo) diff --git a/examples/auth/auth_skel.c b/examples/auth/auth_skel.c new file mode 100644 index 0000000000..e6cbd73968 --- /dev/null +++ b/examples/auth/auth_skel.c @@ -0,0 +1,58 @@ +/* + Unix SMB/CIFS implementation. + Password and authentication handling + Copyright (C) Andrew Bartlett 2001 + Copyright (C) Jelmer Vernooij 2003 + + 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/>. +*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +static NTSTATUS check_skel_security(const struct auth_context *auth_context, + void *my_private_data, + TALLOC_CTX *mem_ctx, + const auth_usersupplied_info *user_info, + auth_serversupplied_info **server_info) +{ + if (!user_info || !auth_context) { + return NT_STATUS_LOGON_FAILURE; + } + + /* Insert your authentication checking code here, + * and return NT_STATUS_OK if authentication succeeds */ + + /* For now, just refuse all connections */ + return NT_STATUS_LOGON_FAILURE; +} + +/* module initialisation */ +NTSTATUS auth_init_skel(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +{ + if (!make_auth_methods(auth_context, auth_method)) { + return NT_STATUS_NO_MEMORY; + } + + (*auth_method)->auth = check_skel_security; + (*auth_method)->name = "skel"; + return NT_STATUS_OK; +} + +NTSTATUS init_module(void) +{ + return smb_register_auth(AUTH_INTERFACE_VERSION, "skel", auth_init_skel); +} diff --git a/examples/auth/crackcheck/Makefile b/examples/auth/crackcheck/Makefile new file mode 100644 index 0000000000..84377aafef --- /dev/null +++ b/examples/auth/crackcheck/Makefile @@ -0,0 +1,25 @@ +# C compiler +#CC=cc +CC=gcc + +# Uncomment the following to add symbols to the code for debugging +#DEBUG=-g -Wall + +# Optimization for the compiler +#OPTIMIZE= +OPTIMIZE=-O2 + +CFLAGS= $(DEBUG) $(OPTIMIZE) + +OBJS = crackcheck.o +LIBS = -lcrack + +crackcheck: $(OBJS) + $(CC) $(CFLAGS) $(LIBS) -o crackcheck $(OBJS) + +clean: + rm -f core *.o crackcheck + +install: crackcheck + install -m 555 crackcheck $(PREFIX)/sbin/crackcheck + diff --git a/examples/auth/crackcheck/crackcheck.c b/examples/auth/crackcheck/crackcheck.c new file mode 100644 index 0000000000..ac29b22592 --- /dev/null +++ b/examples/auth/crackcheck/crackcheck.c @@ -0,0 +1,140 @@ +#include <memory.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <crack.h> + +void usage(char *command) { + char *c, *comm; + + comm = command; + while ((c = strrchr(comm, '/')) != NULL) { + comm = c + 1; + } + + fprintf(stderr, "Usage: %s [-c] [-s] [-d <dictionary>]\n\n", comm); + fprintf(stderr, " -c enables NT like complexity checks\n"); + fprintf(stderr, " -d <dictionary file> for cracklib\n"); + fprintf(stderr, " -s simple check use NT like checks ONLY\n\n"); + fprintf(stderr, "The password is read via stdin.\n\n"); + exit(-1); +} + +int complexity(char* passwd) +{ + /* TG 26.10.2005 + * check password for complexity like MS Windows NT + */ + + int c_upper = 0; + int c_lower = 0; + int c_digit = 0; + int c_punct = 0; + int c_tot = 0; + int i, len; + + if (!passwd) goto fail; + len = strlen(passwd); + + for (i = 0; i < len; i++) { + + if (c_tot >= 3) break; + + if (isupper(passwd[i])) { + if (!c_upper) { + c_upper = 1; + c_tot += 1; + } + continue; + } + if (islower(passwd[i])) { + if (!c_lower) { + c_lower = 1; + c_tot += 1; + } + continue; + } + if (isdigit(passwd[i])) { + if (!c_digit) { + c_digit = 1; + c_tot += 1; + } + continue; + } + if (ispunct(passwd[i])) { + if (!c_punct) { + c_punct = 1; + c_tot += 1; + } + continue; + } + } + + if ((c_tot) < 3) goto fail; + return 0; + +fail: + fprintf(stderr, "ERR Complexity check failed\n\n"); + return -4; +} + +int main(int argc, char **argv) { + extern char *optarg; + int c, ret, complex_check = 0, simplex_check = 0; + + char f[256]; + char *dictionary = NULL; + char *password; + char *reply; + + while ( (c = getopt(argc, argv, "d:cs")) != EOF){ + switch(c) { + case 'd': + dictionary = strdup(optarg); + break; + case 'c': + complex_check = 1; + break; + case 's': + complex_check = 1; + simplex_check = 1; + break; + default: + usage(argv[0]); + } + } + + if (!simplex_check && dictionary == NULL) { + fprintf(stderr, "ERR - Missing cracklib dictionary\n\n"); + usage(argv[0]); + } + + fflush(stdin); + password = fgets(f, sizeof(f), stdin); + + if (password == NULL) { + fprintf(stderr, "ERR - Failed to read password\n\n"); + exit(-2); + } + + if (complex_check) { + ret = complexity(password); + if (ret) { + exit(ret); + } + } + + if (simplex_check) { + exit(0); + } + + reply = FascistCheck(password, dictionary); + if (reply != NULL) { + fprintf(stderr, "ERR - %s\n\n", reply); + exit(-3); + } + + exit(0); +} + diff --git a/examples/autofs/auto.smb b/examples/autofs/auto.smb new file mode 100644 index 0000000000..eb24cfaab4 --- /dev/null +++ b/examples/autofs/auto.smb @@ -0,0 +1,11 @@ +# automount points below /smb + +# This is an automounter map and it has the following format +# key [ -mount-options-separated-by-comma ] location +# Details may be found in the autofs(5) manpage + +# smb-servers +supra_andreas -fstype=smb,username=andreas,password=foo ://supra/aheinrich +supra_cspiel -fstype=smb,username=cspiel ://supra/cspiel +phonon_andreas -fstype=smb,username=andreas ://phonon/andreas +helium_cspiel -fstype=smb,username=cspiel ://helium/cspiel diff --git a/examples/dce-dfs/README b/examples/dce-dfs/README new file mode 100644 index 0000000000..4aaba8bb33 --- /dev/null +++ b/examples/dce-dfs/README @@ -0,0 +1,4 @@ +this is a sample configuration file from Jim Doyle <doyle@oec.com> who +did the DCE/DFS patches for Samba. It shows how to make DCE/DFS shares +available. + diff --git a/examples/dce-dfs/smb.conf b/examples/dce-dfs/smb.conf new file mode 100644 index 0000000000..f5f155b8e6 --- /dev/null +++ b/examples/dce-dfs/smb.conf @@ -0,0 +1,42 @@ +[global] + printing = bsd + printcap name = /etc/printcap + load printers = no + guest account = guest + log file = /usr/local/samba/var/log.%m + log level = 8 + password level = 8 + +[homes] + comment = Home Directories + browseable = no + read only = no + create mode = 0750 + +[test] + comment = test stuff + path = /dept/mis/home/testacct + valid users = testacct + public = no + writable = yes + +[namespace] + comment = DCE-DFS Global Root + path = /... + public = no + writable = yes + +[oecdfs] + comment = Corporate Cell + path = /.../corp.boston.oec.com/fs + browseable = no + read only = no + create mode = 0750 + +[develdfs] + comment = Technology Development Cell + path = /.../devel.boston.oec.com/fs + browseable = no + read only = no + create mode = 0750 + diff --git a/examples/libsmbclient/Makefile b/examples/libsmbclient/Makefile new file mode 100644 index 0000000000..047addc8f7 --- /dev/null +++ b/examples/libsmbclient/Makefile @@ -0,0 +1,106 @@ +# +CC = gcc + +SAMBA_INCL = -I/usr/local/samba/include +EXTLIB_INCL = -I/usr/include/gtk-1.2 \ + -I/usr/include/glib-1.2 \ + -I/usr/lib/glib/include +EXTLIB_INCL = `gtk-config --cflags` + +DEFS = -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +CFLAGS = -O0 -g $(SAMBA_INCL) $(EXTLIB_INCL) $(DEFS) + +LDFLAGS = -L/usr/local/samba/lib \ + -lldap -lkrb5 -lgssapi_krb5 +#LIBSMBCLIENT = /usr/local/samba/lib/libsmbclient.so +LIBSMBCLIENT = -lwbclient -lsmbclient -ltalloc -ltdb -ldl -lresolv + +TESTS= testsmbc \ + testacl \ + testacl2 \ + testacl3 \ + testbrowse \ + testbrowse2 \ + teststat \ + teststat2 \ + teststat3 \ + testtruncate \ + testchmod \ + testutime \ + testread \ + testwrite + +# tree \ + +all: $(TESTS) smbsh + +testsmbc: testsmbc.o + @echo Linking testsmbc + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) + +tree: tree.o + @echo Linking tree + $(CC) `gtk-config --cflags` $(CFLAGS) $(LDFLAGS) -o $@ $< `gtk-config --libs` $(LIBSMBCLIENT) + +testacl: testacl.o + @echo Linking testacl + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +testacl2: testacl2.o + @echo Linking testacl2 + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +testacl3: testacl3.o + @echo Linking testacl3 + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +testbrowse: testbrowse.o + @echo Linking testbrowse + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +testbrowse2: testbrowse2.o + @echo Linking testbrowse2 + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +teststat: teststat.o + @echo Linking teststat + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +teststat2: teststat2.o + @echo Linking teststat2 + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +teststat3: teststat3.o + @echo Linking teststat3 + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +testtruncate: testtruncate.o + @echo Linking testtruncate + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +testchmod: testchmod.o + @echo Linking testchmod + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +testutime: testutime.o + @echo Linking testutime + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +testread: testread.o + @echo Linking testread + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +testwrite: testwrite.o + @echo Linking testwrite + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +testctx: testctx.o + @echo Linking testctx + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + +smbsh: + make -C smbwrapper + +clean: + @rm -f *.o *~ $(TESTS) + @make -C smbwrapper clean diff --git a/examples/libsmbclient/Makefile.internal.in b/examples/libsmbclient/Makefile.internal.in new file mode 100644 index 0000000000..dd4518f212 --- /dev/null +++ b/examples/libsmbclient/Makefile.internal.in @@ -0,0 +1,138 @@ +# Makefile.internal.in for building the libsmbclient examples +# from within a samba build. +# +# Use Makfile for building the examples with a libsmbclient +# installed to /usr/local/samba + +CC = @CC@ + +SAMBA_DIR = ../../source +SAMBA_INCLUDES = -I$(SAMBA_DIR)/include +SAMBA_LIBPATH = -L$(SAMBA_DIR)/bin + +GTK_CFLAGS = `gtk-config --cflags` +GTK_LIBS = `gtk-config --libs` + +#GTK_CFLAGS = `pkg-config gtk+-2.0 --cflags` +#GTK_LIBS = `pkg-config gtk+-2.0 --libs` + +FLAGS = @CPPFLAGS@ @CFLAGS@ $(GTK_CFLAGS) $(SAMBA_INCLUDES) + +PICFLAG=@PICFLAG@ +LDFLAGS= $(SAMBA_LIBPATH) @PIE_LDFLAGS@ @LDFLAGS@ + +EXTERNAL_LIBS = @LIBS@ @LDAP_LIBS@ @KRB5_LIBS@ @NSCD_LIBS@ +LIBSMBCLIENT_LIBS = -lwbclient -lsmbclient -ltalloc -ltdb -ldl -lresolv +CMDLINE_LIBS = @POPTLIBS@ +LIBS = $(EXTERNAL_LIBS) $(LIBSMBCLIENT_LIBS) + +# Compile a source file. (.c --> .o) +COMPILE_CC = $(CC) -I. $(FLAGS) $(PICFLAG) -c $< -o $@ +COMPILE = $(COMPILE_CC) + +MAKEDIR = || exec false; \ + if test -d "$$dir"; then :; else \ + echo mkdir "$$dir"; \ + mkdir -p "$$dir" >/dev/null 2>&1 || \ + test -d "$$dir" || \ + mkdir "$$dir" || \ + exec false; fi || exec false + +TESTS= testsmbc \ + testacl \ + testacl2 \ + testacl3 \ + testbrowse \ + testbrowse2 \ + teststat \ + teststat2 \ + teststat3 \ + testtruncate \ + testchmod \ + testutime \ + testread \ + testwrite + +# tree \ + +all: $(TESTS) smbsh + +.c.o: + @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ + dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi + @echo Compiling $*.c + @$(COMPILE) && exit 0;\ + echo "The following command failed:" 1>&2;\ + echo "$(COMPILE_CC)" 1>&2;\ + $(COMPILE_CC) >/dev/null 2>&1 + +testsmbc: testsmbc.o + @echo Linking testsmbc + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) + +tree: tree.o + @echo Linking tree + @$(CC) $(GTK_CFLAGS) $(FLAGS) $(LDFLAGS) -o $@ $< $(GTK_LIBS) $(LIBS) + +testacl: testacl.o + @echo Linking testacl + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testacl2: testacl2.o + @echo Linking testacl2 + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testacl3: testacl3.o + @echo Linking testacl3 + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testbrowse: testbrowse.o + @echo Linking testbrowse + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testbrowse2: testbrowse2.o + @echo Linking testbrowse2 + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +teststat: teststat.o + @echo Linking teststat + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +teststat2: teststat2.o + @echo Linking teststat2 + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +teststat3: teststat3.o + @echo Linking teststat3 + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testtruncate: testtruncate.o + @echo Linking testtruncate + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testchmod: testchmod.o + @echo Linking testchmod + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testutime: testutime.o + @echo Linking testutime + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testread: testread.o + @echo Linking testread + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testwrite: testwrite.o + @echo Linking testwrite + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testctx: testctx.o + @echo Linking testctx + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +smbsh: + make -C smbwrapper + +clean: + @rm -f *.o *~ $(TESTS) + @make -C smbwrapper clean diff --git a/examples/libsmbclient/README b/examples/libsmbclient/README new file mode 100644 index 0000000000..c45dd8b9d6 --- /dev/null +++ b/examples/libsmbclient/README @@ -0,0 +1,17 @@ +Some simple example programs for libsmbclient ... + +testsmbc.c is kinda broken as it has many hardcoded bits in it + +testbrowse.c opens a remote folder and displays its contents + +teststat.c allows comparing the results of smbc_stat() against a local stat() of +the same file. + +tree.c is an example of how you might do some of these things with GTK+ +It needs lots of work but shows you some ways to use libsmbclient. + +smbwrapper implements the old smbsh/smbwrapper mechanism using libsmbclient, in +such a way that it works on Linux + +Richard Sharpe, 17 May 2001 +Derrell Lipman, 30 Mar 2005 diff --git a/examples/libsmbclient/get_auth_data_fn.h b/examples/libsmbclient/get_auth_data_fn.h new file mode 100644 index 0000000000..6b91c97337 --- /dev/null +++ b/examples/libsmbclient/get_auth_data_fn.h @@ -0,0 +1,82 @@ +#include <stdlib.h> + +static void +get_auth_data_fn(const char * pServer, + const char * pShare, + char * pWorkgroup, + int maxLenWorkgroup, + char * pUsername, + int maxLenUsername, + char * pPassword, + int maxLenPassword) +{ + char temp[128]; + char server[256] = { '\0' }; + char share[256] = { '\0' }; + char workgroup[256] = { '\0' }; + char username[256] = { '\0' }; + char password[256] = { '\0' }; + + static int krb5_set = 1; + + if (strcmp(server, pServer) == 0 && + strcmp(share, pShare) == 0 && + *workgroup != '\0' && + *username != '\0') + { + strncpy(pWorkgroup, workgroup, maxLenWorkgroup - 1); + strncpy(pUsername, username, maxLenUsername - 1); + strncpy(pPassword, password, maxLenPassword - 1); + return; + } + + if (krb5_set && getenv("KRB5CCNAME")) { + krb5_set = 0; + return; + } + + fprintf(stdout, "Workgroup: [%s] ", pWorkgroup); + fgets(temp, sizeof(temp), stdin); + + if (temp[strlen(temp) - 1] == '\n') /* A new line? */ + { + temp[strlen(temp) - 1] = '\0'; + } + + if (temp[0] != '\0') + { + strncpy(pWorkgroup, temp, maxLenWorkgroup - 1); + } + + fprintf(stdout, "Username: [%s] ", pUsername); + fgets(temp, sizeof(temp), stdin); + + if (temp[strlen(temp) - 1] == '\n') /* A new line? */ + { + temp[strlen(temp) - 1] = '\0'; + } + + if (temp[0] != '\0') + { + strncpy(pUsername, temp, maxLenUsername - 1); + } + + fprintf(stdout, "Password: "); + fgets(temp, sizeof(temp), stdin); + + if (temp[strlen(temp) - 1] == '\n') /* A new line? */ + { + temp[strlen(temp) - 1] = '\0'; + } + + if (temp[0] != '\0') + { + strncpy(pPassword, temp, maxLenPassword - 1); + } + + strncpy(workgroup, pWorkgroup, sizeof(workgroup) - 1); + strncpy(username, pUsername, sizeof(username) - 1); + strncpy(password, pPassword, sizeof(password) - 1); + + krb5_set = 1; +} diff --git a/examples/libsmbclient/smbwrapper/Makefile b/examples/libsmbclient/smbwrapper/Makefile new file mode 100644 index 0000000000..eb470056e1 --- /dev/null +++ b/examples/libsmbclient/smbwrapper/Makefile @@ -0,0 +1,39 @@ +LIBS = -lwbclient -lsmbclient -ltalloc -ltdb -ldl +DEFS = -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE + +CFLAGS = -I$(SAMBA_INCL) $(EXTLIB_INCL) + +LDFLAGS = -L/usr/local/samba/lib -L../../../source/bin + +SMBINCLUDE = -I../../../source/include +CFLAGS= -fpic -g -O0 $(DEFS) $(SMBINCLUDE) + +BIN = . + +STRFUNC = bsd-strlcat.o bsd-strlcpy.o + + +SMBWRAPPER_OBJS = smbw.o smbw_dir.o smbw_stat.o wrapper.o select.o $(STRFUNC) +SMBSH_OBJS = smbsh.o $(STRFUNC) + +all: $(BIN)/smbwrapper.so $(BIN)/smbsh + +$(BIN)/smbwrapper.so: $(SMBWRAPPER_OBJS) + $(CC) -g \ + -Wl,-init=smbw_initialize \ + -shared \ + --export-all-symbols \ + -o $(BIN)/smbwrapper.so \ + $(SMBWRAPPER_OBJS) \ + $(LDFLAGS) \ + $(LIBS) \ + -Wl,-soname=`basename $@` + +$(BIN)/smbsh: $(SMBSH_OBJS) + $(CC) -g -o $(BIN)/smbsh $(SMBSH_OBJS) $(LIBS) $(LDFLAGS) + +opendir_smbsh: opendir_smbsh.o + $(CC) -g -o opendir_smbsh opendir_smbsh.o $(LIBS) $(DMALLOC) + +clean: + rm -f *.o *~ opendir_smbsh smbsh smbwrapper.so diff --git a/examples/libsmbclient/smbwrapper/README b/examples/libsmbclient/smbwrapper/README new file mode 100644 index 0000000000..7b71ec06ba --- /dev/null +++ b/examples/libsmbclient/smbwrapper/README @@ -0,0 +1,40 @@ +To create "smbsh" on Linux, just type "make". + +If you execute "smbsh" in *this* directory (so that it can find the required +shared library), you'll find yourself in a new shell. You can then issue +commands referencing the "/smb" pseudo-filesystem: + + ls /smb + ls /smb/WORKGROUP_OR_DOMAIN + ls /smb/SERVER + ls /smb/SERVER/SHARE + ls /smb/SERVER/SHARE/PATH + +Note that WORKGROUP_OR_DOMAIN is *not* used other than at that level. This is +consistent with the smb:// URI definition. + +Usage: + smbsh [-L <path to find smbwrapper.so>] + [-p <library to load before smbwrapper.so>] + [-a <library to load after smbwrapper.so>] + [-d <debug value for libsmbclient>] + [-n] (do not ask for username/password) + [-W <workgroup>] + [-U <username%password] + [command] + +So to list the contents of \\MYDESK\C$ where a username (adventure) and password +(xyzzy) are required, and with smbwrapper.so installed in /usr/share/samba, you +could try: + + smbsh -L /usr/share/samba -U adventure%xyzzy ls '/smb/MYDESK/C$' + +(It's a good idea to get in the habit of surrounding windows paths in single +quotes, since they often contain spaces and other characters that'll give you +headaches when not escaped.) + +This smbsh seems to work quite well on Linux 2.4 and 2.6. The biggest problem it +has is in tracking your current working directory. I haven't had the time to +track that down and fix it. + +Derrell Lipman diff --git a/examples/libsmbclient/smbwrapper/bsd-strlcat.c b/examples/libsmbclient/smbwrapper/bsd-strlcat.c new file mode 100644 index 0000000000..d82ced3e8a --- /dev/null +++ b/examples/libsmbclient/smbwrapper/bsd-strlcat.c @@ -0,0 +1,71 @@ +/* $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This version has been modified for inclusion in Samba. + * It has been converted to ANSI C from old-style K&R C. + */ + +#include <sys/types.h> +#include <string.h> + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +smbw_strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff --git a/examples/libsmbclient/smbwrapper/bsd-strlcpy.c b/examples/libsmbclient/smbwrapper/bsd-strlcpy.c new file mode 100644 index 0000000000..9f7e55da8e --- /dev/null +++ b/examples/libsmbclient/smbwrapper/bsd-strlcpy.c @@ -0,0 +1,67 @@ +/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This version has been modified for inclusion in Samba. + * It has been converted to ANSI C from old-style K&R C. + */ + +#include <sys/types.h> +#include <string.h> + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +smbw_strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} diff --git a/examples/libsmbclient/smbwrapper/bsd-strlfunc.h b/examples/libsmbclient/smbwrapper/bsd-strlfunc.h new file mode 100644 index 0000000000..fb3a045ac6 --- /dev/null +++ b/examples/libsmbclient/smbwrapper/bsd-strlfunc.h @@ -0,0 +1,7 @@ +#ifndef __BSD_STRLFUNC_H__ + +extern size_t strlcpy(char *dst, const char *src, size_t siz); +extern size_t strlcat(char *dst, const char *src, size_t siz); + +#define __BSD_STRLFUNC_H__ +#endif diff --git a/examples/libsmbclient/smbwrapper/opendir_smbsh.c b/examples/libsmbclient/smbwrapper/opendir_smbsh.c new file mode 100644 index 0000000000..275b95f8ea --- /dev/null +++ b/examples/libsmbclient/smbwrapper/opendir_smbsh.c @@ -0,0 +1,47 @@ +#include <sys/types.h> +#include <dirent.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <libsmbclient.h> + +int +main(int argc, char * argv[]) +{ + char * p; + char buf[1024]; + DIR * dir; + struct dirent * dirent; + + setbuf(stdout, NULL); + + for (fputs("path: ", stdout), p = fgets(buf, sizeof(buf), stdin); + p != NULL && *p != '\n' && *p != '\0'; + fputs("path: ", stdout), p = fgets(buf, sizeof(buf), stdin)) + { + if ((p = strchr(buf, '\n')) != NULL) + { + *p = '\0'; + } + + printf("Opening (%s)...\n", buf); + + if ((dir = opendir(buf)) == NULL) + { + printf("Could not open directory [%s]: \n", + buf, strerror(errno)); + continue; + } + + while ((dirent = readdir(dir)) != NULL) + { + printf("%-30s", dirent->d_name); + printf("%-30s", dirent->d_name + strlen(dirent->d_name) + 1); + printf("\n"); + } + + closedir(dir); + } + + exit(0); +} diff --git a/examples/libsmbclient/smbwrapper/select.c b/examples/libsmbclient/smbwrapper/select.c new file mode 100644 index 0000000000..bb7a25f13e --- /dev/null +++ b/examples/libsmbclient/smbwrapper/select.c @@ -0,0 +1,122 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + Samba select/poll implementation + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Derrell Lipman 2003-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/>. +*/ + +/* + * WHY THIS FILE? + * + * This file implements the two functions in the select() family, as required + * by samba. The samba native functions, though, implement a pipe to help + * alleviate a deadlock problem, but which creates problems of its own (the + * timeout stops working correctly). Those functions also require that all + * signal handlers call a function which writes to the pipe -- a task which is + * difficult to do in the smbwrapper environment. + */ + + +#include <sys/select.h> +#include <errno.h> +#include <stdio.h> + +int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval) +{ + int ret; + fd_set *readfds2, readfds_buf; + + /* If readfds is NULL we need to provide our own set. */ + if (readfds) { + readfds2 = readfds; + } else { + readfds2 = &readfds_buf; + FD_ZERO(readfds2); + } + + errno = 0; + ret = select(maxfd,readfds2,writefds,errorfds,tval); + + if (ret <= 0) { + FD_ZERO(readfds2); + if (writefds) + FD_ZERO(writefds); + if (errorfds) + FD_ZERO(errorfds); + } + + return ret; +} + +/******************************************************************* + Similar to sys_select() but catch EINTR and continue. + This is what sys_select() used to do in Samba. +********************************************************************/ + +int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval) +{ + int ret; + fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf; + struct timeval tval2, *ptval, end_time, now_time; + + readfds2 = (readfds ? &readfds_buf : NULL); + writefds2 = (writefds ? &writefds_buf : NULL); + errorfds2 = (errorfds ? &errorfds_buf : NULL); + if (tval) { + gettimeofday(&end_time, NULL); + end_time.tv_sec += tval->tv_sec; + end_time.tv_usec += tval->tv_usec; + end_time.tv_sec += end_time.tv_usec / 1000000; + end_time.tv_usec %= 1000000; + ptval = &tval2; + } else { + ptval = NULL; + } + + do { + if (readfds) + readfds_buf = *readfds; + if (writefds) + writefds_buf = *writefds; + if (errorfds) + errorfds_buf = *errorfds; + if (tval) { + gettimeofday(&now_time, NULL); + tval2.tv_sec = end_time.tv_sec - now_time.tv_sec; + tval2.tv_usec = end_time.tv_usec - now_time.tv_usec; + if ((signed long) tval2.tv_usec < 0) { + tval2.tv_usec += 1000000; + tval2.tv_sec--; + } + if ((signed long) tval2.tv_sec < 0) { + ret = 0; + break; /* time has already elapsed */ + } + } + + ret = sys_select(maxfd, readfds2, writefds2, errorfds2, ptval); + } while (ret == -1 && errno == EINTR); + + if (readfds) + *readfds = readfds_buf; + if (writefds) + *writefds = writefds_buf; + if (errorfds) + *errorfds = errorfds_buf; + + return ret; +} diff --git a/examples/libsmbclient/smbwrapper/smbsh.1 b/examples/libsmbclient/smbwrapper/smbsh.1 new file mode 100644 index 0000000000..368a245e17 --- /dev/null +++ b/examples/libsmbclient/smbwrapper/smbsh.1 @@ -0,0 +1,203 @@ +.\" Title: smbsh +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.73.1 <http://docbook.sf.net/> +.\" Date: 06/12/2008 +.\" Manual: User Commands +.\" Source: Samba 3.2 +.\" +.TH "SMBSH" "1" "06/12/2008" "Samba 3\.2" "User Commands" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +smbsh - Allows access to remote SMB shares using UNIX commands +.SH "SYNOPSIS" +.HP 1 +smbsh [\-W\ workgroup] [\-U\ username] [\-P\ prefix] [\-R\ <name\ resolve\ order>] [\-d\ <debug\ level>] [\-l\ logdir] [\-L\ libdir] +.SH "DESCRIPTION" +.PP +This tool is part of the +\fBsamba\fR(7) +suite\. +.PP +smbsh +allows you to access an NT filesystem using UNIX commands such as +ls, +egrep, and +rcp\. You must use a shell that is dynamically linked in order for +smbsh +to work correctly\. +.SH "OPTIONS" +.PP +\-W WORKGROUP +.RS 4 +Override the default workgroup specified in the workgroup parameter of the +\fBsmb.conf\fR(5) +file for this session\. This may be needed to connect to some servers\. +.RE +.PP +\-U username[%pass] +.RS 4 +Sets the SMB username or username and password\. If this option is not specified, the user will be prompted for both the username and the password\. If %pass is not specified, the user will be prompted for the password\. +.RE +.PP +\-P prefix +.RS 4 +This option allows the user to set the directory prefix for SMB access\. The default value if this option is not specified is +\fIsmb\fR\. +.RE +.PP +\-s <configuration file> +.RS 4 +The file specified contains the configuration details required by the server\. The information in this file includes server\-specific information such as what printcap file to use, as well as descriptions of all the services that the server is to provide\. See +\fIsmb\.conf\fR +for more information\. The default configuration file name is determined at compile time\. +.RE +.PP +\-d|\-\-debuglevel=level +.RS 4 +\fIlevel\fR +is an integer from 0 to 10\. The default value if this parameter is not specified is 0\. +.sp +The higher this value, the more detail will be logged to the log files about the activities of the server\. At level 0, only critical errors and serious warnings will be logged\. Level 1 is a reasonable level for day\-to\-day running \- it generates a small amount of information about operations carried out\. +.sp +Levels above 1 will generate considerable amounts of log data, and should only be used when investigating a problem\. Levels above 3 are designed for use only by developers and generate HUGE amounts of log data, most of which is extremely cryptic\. +.sp +Note that specifying this parameter here will override the +\fIlog level\fR +parameter in the +\fIsmb\.conf\fR +file\. +.RE +.PP +\-R <name resolve order> +.RS 4 +This option is used to determine what naming services and in what order to resolve host names to IP addresses\. The option takes a space\-separated string of different name resolution options\. +.sp +The options are: "lmhosts", "host", "wins" and "bcast"\. They cause names to be resolved as follows : +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +\fBlmhosts\fR: Lookup an IP address in the Samba lmhosts file\. If the line in lmhosts has no name type attached to the NetBIOS name (see the +\fBlmhosts\fR(5) +for details) then any name type matches for lookup\. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +\fBhost\fR: Do a standard host name to IP address resolution, using the system +\fI/etc/hosts\fR, NIS, or DNS lookups\. This method of name resolution is operating system dependent, for instance on IRIX or Solaris this may be controlled by the +\fI/etc/nsswitch\.conf \fR +file)\. Note that this method is only used if the NetBIOS name type being queried is the 0x20 (server) name type, otherwise it is ignored\. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +\fBwins\fR: Query a name with the IP address listed in the +\fIwins server\fR +parameter\. If no WINS server has been specified this method will be ignored\. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +\fBbcast\fR: Do a broadcast on each of the known local interfaces listed in the +\fIinterfaces\fR +parameter\. This is the least reliable of the name resolution methods as it depends on the target host being on a locally connected subnet\. +.sp +.RE +If this parameter is not set then the name resolve order defined in the +\fIsmb\.conf\fR +file parameter (\fIname resolve order\fR) will be used\. +.sp +The default order is lmhosts, host, wins, bcast\. Without this parameter or any entry in the +\fIname resolve order\fR +parameter of the +\fIsmb\.conf\fR +file, the name resolution methods will be attempted in this order\. +.RE +.PP +\-L libdir +.RS 4 +This parameter specifies the location of the shared libraries used by +smbsh\. The default value is specified at compile time\. +.RE +.SH "EXAMPLES" +.PP +To use the +smbsh +command, execute +smbsh +from the prompt and enter the username and password that authenticates you to the machine running the Windows NT operating system\. +.sp +.RS 4 +.nf +system% \fBsmbsh\fR +Username: \fBuser\fR +Password: \fBXXXXXXX\fR +.fi +.RE +.PP +Any dynamically linked command you execute from this shell will access the +\fI/smb\fR +directory using the smb protocol\. For example, the command +ls /smb +will show a list of workgroups\. The command +ls /smb/MYGROUP +will show all the machines in the workgroup MYGROUP\. The command +ls /smb/MYGROUP/<machine\-name> +will show the share names for that machine\. You could then, for example, use the +cd +command to change directories, +vi +to edit files, and +rcp +to copy files\. +.SH "VERSION" +.PP +This man page is correct for version 3 of the Samba suite\. +.SH "BUGS" +.PP +smbsh +works by intercepting the standard libc calls with the dynamically loaded versions in +\fI smbwrapper\.o\fR\. Not all calls have been "wrapped", so some programs may not function correctly under +smbsh\. +.PP +Programs which are not dynamically linked cannot make use of +smbsh\'s functionality\. Most versions of UNIX have a +file +command that will describe how a program was linked\. +.SH "SEE ALSO" +.PP +\fBsmbd\fR(8), +\fBsmb.conf\fR(5) +.SH "AUTHOR" +.PP +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\. +.PP +The original Samba man pages were written by Karl Auer\. The man page sources were converted to YODL format (another excellent piece of Open Source software, available at +ftp://ftp\.icce\.rug\.nl/pub/unix/) and updated for the Samba 2\.0 release by Jeremy Allison\. The conversion to DocBook for Samba 2\.2 was done by Gerald Carter\. The conversion to DocBook XML 4\.2 for Samba 3\.0 was done by Alexander Bokovoy\. diff --git a/examples/libsmbclient/smbwrapper/smbsh.1.html b/examples/libsmbclient/smbwrapper/smbsh.1.html new file mode 100644 index 0000000000..a13451149d --- /dev/null +++ b/examples/libsmbclient/smbwrapper/smbsh.1.html @@ -0,0 +1,108 @@ +<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>smbsh</title><link rel="stylesheet" href="../samba.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.73.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en"><a name="smbsh.1"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>smbsh — Allows access to remote SMB shares + using UNIX commands</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="literal">smbsh</code> [-W workgroup] [-U username] [-P prefix] [-R <name resolve order>] [-d <debug level>] [-l logdir] [-L libdir]</p></div></div><div class="refsect1" lang="en"><a name="id2507195"></a><h2>DESCRIPTION</h2><p>This tool is part of the <a class="citerefentry" href="samba.7.html"><span class="citerefentry"><span class="refentrytitle">samba</span>(7)</span></a> suite.</p><p><code class="literal">smbsh</code> allows you to access an NT filesystem + using UNIX commands such as <code class="literal">ls</code>, <code class="literal"> + egrep</code>, and <code class="literal">rcp</code>. You must use a + shell that is dynamically linked in order for <code class="literal">smbsh</code> + to work correctly.</p></div><div class="refsect1" lang="en"><a name="id2507248"></a><h2>OPTIONS</h2><div class="variablelist"><dl><dt><span class="term">-W WORKGROUP</span></dt><dd><p>Override the default workgroup specified in the + workgroup parameter of the <a class="citerefentry" href="smb.conf.5.html"><span class="citerefentry"><span class="refentrytitle">smb.conf</span>(5)</span></a> file + for this session. This may be needed to connect to some + servers. </p></dd><dt><span class="term">-U username[%pass]</span></dt><dd><p>Sets the SMB username or username and password. + If this option is not specified, the user will be prompted for + both the username and the password. If %pass is not specified, + the user will be prompted for the password. + </p></dd><dt><span class="term">-P prefix</span></dt><dd><p>This option allows + the user to set the directory prefix for SMB access. The + default value if this option is not specified is + <span class="emphasis"><em>smb</em></span>. + </p></dd><dt><span class="term">-s <configuration file></span></dt><dd><p>The file specified contains the +configuration details required by the server. The +information in this file includes server-specific +information such as what printcap file to use, as well +as descriptions of all the services that the server is +to provide. See <code class="filename">smb.conf</code> for more information. +The default configuration file name is determined at +compile time.</p></dd><dt><span class="term">-d|--debuglevel=level</span></dt><dd><p><em class="replaceable"><code>level</code></em> is an integer +from 0 to 10. The default value if this parameter is +not specified is 0.</p><p>The higher this value, the more detail will be +logged to the log files about the activities of the +server. At level 0, only critical errors and serious +warnings will be logged. Level 1 is a reasonable level for +day-to-day running - it generates a small amount of +information about operations carried out.</p><p>Levels above 1 will generate considerable +amounts of log data, and should only be used when +investigating a problem. Levels above 3 are designed for +use only by developers and generate HUGE amounts of log +data, most of which is extremely cryptic.</p><p>Note that specifying this parameter here will +override the <a class="link" href="smb.conf.5.html#LOGLEVEL">log level</a> parameter +in the <code class="filename">smb.conf</code> file.</p></dd><dt><span class="term">-R <name resolve order></span></dt><dd><p>This option is used to determine what naming +services and in what order to resolve +host names to IP addresses. The option takes a space-separated +string of different name resolution options.</p><p>The options are: "lmhosts", "host", "wins" and "bcast". +They cause names to be resolved as follows :</p><div class="itemizedlist"><ul type="disc"><li><p><code class="constant">lmhosts</code>: +Lookup an IP address in the Samba lmhosts file. If the +line in lmhosts has no name type attached to the +NetBIOS name +(see the <a class="citerefentry" href="lmhosts.5.html"><span class="citerefentry"><span class="refentrytitle">lmhosts</span>(5)</span></a> for details) +then any name type matches for lookup. +</p></li><li><p><code class="constant">host</code>: +Do a standard host name to IP address resolution, using +the system <code class="filename">/etc/hosts</code>, NIS, or DNS +lookups. This method of name resolution is operating +system dependent, for instance on IRIX or Solaris this +may be controlled by the <code class="filename">/etc/nsswitch.conf +</code> file). Note that this method is only used +if the NetBIOS name type being queried is the 0x20 +(server) name type, otherwise it is ignored. +</p></li><li><p><code class="constant">wins</code>: +Query a name with the IP address listed in the +<em class="parameter"><code>wins server</code></em> parameter. If no +WINS server has been specified this method will be +ignored. +</p></li><li><p><code class="constant">bcast</code>: +Do a broadcast on each of the known local interfaces +listed in the <em class="parameter"><code>interfaces</code></em> +parameter. This is the least reliable of the name +resolution methods as it depends on the target host +being on a locally connected subnet. +</p></li></ul></div><p>If this parameter is not set then the name resolve order +defined in the <code class="filename">smb.conf</code> file parameter +(<a class="link" href="smb.conf.5.html#NAMERESOLVEORDER">name resolve order</a>) will be used. +</p><p>The default order is lmhosts, host, wins, bcast. Without +this parameter or any entry in the <a class="link" href="smb.conf.5.html#NAMERESOLVEORDER">name resolve order</a> parameter of the <code class="filename">smb.conf</code> file, the name +resolution methods will be attempted in this order. </p></dd><dt><span class="term">-L libdir</span></dt><dd><p>This parameter specifies the location of the + shared libraries used by <code class="literal">smbsh</code>. The default + value is specified at compile time. + </p></dd></dl></div></div><div class="refsect1" lang="en"><a name="id2506378"></a><h2>EXAMPLES</h2><p>To use the <code class="literal">smbsh</code> command, execute <code class="literal"> + smbsh</code> from the prompt and enter the username and password + that authenticates you to the machine running the Windows NT + operating system. +</p><pre class="programlisting"> +<code class="prompt">system% </code><strong class="userinput"><code>smbsh</code></strong> +<code class="prompt">Username: </code><strong class="userinput"><code>user</code></strong> +<code class="prompt">Password: </code><strong class="userinput"><code>XXXXXXX</code></strong> +</pre><p>Any dynamically linked command you execute from + this shell will access the <code class="filename">/smb</code> directory + using the smb protocol. For example, the command <code class="literal">ls /smb + </code> will show a list of workgroups. The command + <code class="literal">ls /smb/MYGROUP </code> will show all the machines in + the workgroup MYGROUP. The command + <code class="literal">ls /smb/MYGROUP/<machine-name></code> will show the share + names for that machine. You could then, for example, use the <code class="literal"> + cd</code> command to change directories, <code class="literal">vi</code> to + edit files, and <code class="literal">rcp</code> to copy files.</p></div><div class="refsect1" lang="en"><a name="id2506489"></a><h2>VERSION</h2><p>This man page is correct for version 3 of the Samba suite.</p></div><div class="refsect1" lang="en"><a name="id2506500"></a><h2>BUGS</h2><p><code class="literal">smbsh</code> works by intercepting the standard + libc calls with the dynamically loaded versions in <code class="filename"> + smbwrapper.o</code>. Not all calls have been "wrapped", so + some programs may not function correctly under <code class="literal">smbsh + </code>.</p><p>Programs which are not dynamically linked cannot make + use of <code class="literal">smbsh</code>'s functionality. Most versions + of UNIX have a <code class="literal">file</code> command that will + describe how a program was linked.</p></div><div class="refsect1" lang="en"><a name="id2506547"></a><h2>SEE ALSO</h2><p><a class="citerefentry" href="smbd.8.html"><span class="citerefentry"><span class="refentrytitle">smbd</span>(8)</span></a>, <a class="citerefentry" href="smb.conf.5.html"><span class="citerefentry"><span class="refentrytitle">smb.conf</span>(5)</span></a></p></div><div class="refsect1" lang="en"><a name="id2506570"></a><h2>AUTHOR</h2><p>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.</p><p>The original Samba man pages were written by Karl Auer. + The man page sources were converted to YODL format (another + excellent piece of Open Source software, available at <a class="ulink" href="ftp://ftp.icce.rug.nl/pub/unix/" target="_top"> + ftp://ftp.icce.rug.nl/pub/unix/</a>) and updated for the Samba 2.0 + release by Jeremy Allison. The conversion to DocBook for + Samba 2.2 was done by Gerald Carter. The conversion to DocBook XML 4.2 + for Samba 3.0 was done by Alexander Bokovoy.</p></div></div></body></html> diff --git a/examples/libsmbclient/smbwrapper/smbsh.1.xml b/examples/libsmbclient/smbwrapper/smbsh.1.xml new file mode 100644 index 0000000000..5494f351c3 --- /dev/null +++ b/examples/libsmbclient/smbwrapper/smbsh.1.xml @@ -0,0 +1,164 @@ +<?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="smbsh.1"> + +<refmeta> + <refentrytitle>smbsh</refentrytitle> + <manvolnum>1</manvolnum> + <refmiscinfo class="source">Samba</refmiscinfo> + <refmiscinfo class="manual">User Commands</refmiscinfo> + <refmiscinfo class="version">3.2</refmiscinfo> +</refmeta> + + +<refnamediv> + <refname>smbsh</refname> + <refpurpose>Allows access to remote SMB shares + using UNIX commands</refpurpose> +</refnamediv> + +<refsynopsisdiv> + <cmdsynopsis> + <command>smbsh</command> + <arg choice="opt">-W workgroup</arg> + <arg choice="opt">-U username</arg> + <arg choice="opt">-P prefix</arg> + <arg choice="opt">-R <name resolve order></arg> + <arg choice="opt">-d <debug level></arg> + <arg choice="opt">-l logdir</arg> + <arg choice="opt">-L libdir</arg> + </cmdsynopsis> +</refsynopsisdiv> + +<refsect1> + <title>DESCRIPTION</title> + + <para>This tool is part of the <citerefentry><refentrytitle>samba</refentrytitle> + <manvolnum>7</manvolnum></citerefentry> suite.</para> + + <para><command>smbsh</command> allows you to access an NT filesystem + using UNIX commands such as <command>ls</command>, <command> + egrep</command>, and <command>rcp</command>. You must use a + shell that is dynamically linked in order for <command>smbsh</command> + to work correctly.</para> +</refsect1> + +<refsect1> + <title>OPTIONS</title> + + <variablelist> + <varlistentry> + <term>-W WORKGROUP</term> + <listitem><para>Override the default workgroup specified in the + workgroup parameter of the <citerefentry><refentrytitle>smb.conf</refentrytitle> + <manvolnum>5</manvolnum></citerefentry> file + for this session. This may be needed to connect to some + servers. </para></listitem> + </varlistentry> + + <varlistentry> + <term>-U username[%pass]</term> + <listitem><para>Sets the SMB username or username and password. + If this option is not specified, the user will be prompted for + both the username and the password. If %pass is not specified, + the user will be prompted for the password. + </para></listitem> + </varlistentry> + + <varlistentry> + <term>-P prefix</term> + <listitem><para>This option allows + the user to set the directory prefix for SMB access. The + default value if this option is not specified is + <emphasis>smb</emphasis>. + </para></listitem> + </varlistentry> + + &stdarg.configfile; + &stdarg.server.debug; + &stdarg.resolve.order; + + <varlistentry> + <term>-L libdir</term> + <listitem><para>This parameter specifies the location of the + shared libraries used by <command>smbsh</command>. The default + value is specified at compile time. + </para></listitem> + </varlistentry> + + </variablelist> +</refsect1> + +<refsect1> + <title>EXAMPLES</title> + + <para>To use the <command>smbsh</command> command, execute <command> + smbsh</command> from the prompt and enter the username and password + that authenticates you to the machine running the Windows NT + operating system. +<programlisting> +<prompt>system% </prompt><userinput>smbsh</userinput> +<prompt>Username: </prompt><userinput>user</userinput> +<prompt>Password: </prompt><userinput>XXXXXXX</userinput> +</programlisting></para> + + + <para>Any dynamically linked command you execute from + this shell will access the <filename>/smb</filename> directory + using the smb protocol. For example, the command <command>ls /smb + </command> will show a list of workgroups. The command + <command>ls /smb/MYGROUP </command> will show all the machines in + the workgroup MYGROUP. The command + <command>ls /smb/MYGROUP/<machine-name></command> will show the share + names for that machine. You could then, for example, use the <command> + cd</command> command to change directories, <command>vi</command> to + edit files, and <command>rcp</command> to copy files.</para> +</refsect1> + +<refsect1> + <title>VERSION</title> + + <para>This man page is correct for version 3 of the Samba suite.</para> +</refsect1> + +<refsect1> + <title>BUGS</title> + + <para><command>smbsh</command> works by intercepting the standard + libc calls with the dynamically loaded versions in <filename> + smbwrapper.o</filename>. Not all calls have been "wrapped", so + some programs may not function correctly under <command>smbsh + </command>.</para> + + <para>Programs which are not dynamically linked cannot make + use of <command>smbsh</command>'s functionality. Most versions + of UNIX have a <command>file</command> command that will + describe how a program was linked.</para> +</refsect1> + + +<refsect1> + <title>SEE ALSO</title> + <para><citerefentry><refentrytitle>smbd</refentrytitle> + <manvolnum>8</manvolnum></citerefentry>, <citerefentry><refentrytitle>smb.conf</refentrytitle> + <manvolnum>5</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> + + <para>The original Samba man pages were written by Karl Auer. + The man page sources were converted to YODL format (another + excellent piece of Open Source software, available at <ulink url="ftp://ftp.icce.rug.nl/pub/unix/"> + ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0 + release by Jeremy Allison. The conversion to DocBook for + Samba 2.2 was done by Gerald Carter. The conversion to DocBook XML 4.2 + for Samba 3.0 was done by Alexander Bokovoy.</para> +</refsect1> + +</refentry> diff --git a/examples/libsmbclient/smbwrapper/smbsh.c b/examples/libsmbclient/smbwrapper/smbsh.c new file mode 100644 index 0000000000..f2b5bf49fb --- /dev/null +++ b/examples/libsmbclient/smbwrapper/smbsh.c @@ -0,0 +1,162 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB wrapper functions - frontend + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Derrell Lipman 2003-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/>. +*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <limits.h> +#include <string.h> +#include <libsmbclient.h> +#include "bsd-strlfunc.h" + +#ifndef FALSE +# define FALSE (0) +# define TRUE (! FALSE) +#endif + +static void smbsh_usage(void) +{ + printf("smbsh [options] [command [args] ...]\n\n"); + printf(" -p prepend library name\n"); + printf(" -a append library name\n"); + printf(" -n"); + printf(" -W workgroup\n"); + printf(" -U username\n"); + printf(" -P prefix\n"); + printf(" -R resolve order\n"); + printf(" -d debug level\n"); + printf(" -l logfile\n"); + printf(" -L libdir\n"); + exit(0); +} + +int main(int argc, char *argv[]) +{ + char *p, *u; + char *libd = "."; + char line[PATH_MAX], pre[PATH_MAX], post[PATH_MAX]; + int opt; + int no_ask = 0; + struct stat statbuf; + extern char *optarg; + extern int optind; + + *pre = *post = '\0'; + + while ((opt = getopt(argc, argv, "p:a:d:nL:W:U:h")) != -1) { + switch (opt) { + case 'p': /* prepend library before smbwrapper.so */ + if (*pre != '\0') + smbw_strlcat(pre, " ", sizeof(pre)); + smbw_strlcat(pre, optarg, sizeof(pre)); + break; + + case 'a': /* append library after smbwrapper.so */ + smbw_strlcat(post, " ", sizeof(post)); + smbw_strlcat(post, optarg, sizeof(post)); + break; + + case 'd': + setenv("DEBUG", optarg, TRUE); + break; + + case 'n': /* don't ask for username/password */ + no_ask++; + break; + + case 'L': + libd = optarg; + break; + + case 'W': + setenv("WORKGROUP", optarg, TRUE); + break; + + case 'U': + p = strchr(optarg,'%'); + if (p) { + *p=0; + setenv("PASSWORD", p+1, TRUE); + } + setenv("USER", optarg, TRUE); + break; + + case 'h': + default: + smbsh_usage(); + } + } + + + if (! no_ask) { + if (!getenv("USER")) { + printf("Username: "); + u = fgets(line, sizeof(line)-1, stdin); + setenv("USER", u, TRUE); + } + + if (!getenv("PASSWORD")) { + p = getpass("Password: "); + setenv("PASSWORD", p, TRUE); + } + } + + smbw_strlcpy(line, pre, PATH_MAX - strlen(line)); + smbw_strlcat(line, " ", sizeof(line)); + smbw_strlcat(line, libd, sizeof(line)); + smbw_strlcat(line, "/smbwrapper.so", sizeof(line)); + smbw_strlcat(line, post, sizeof(line)); + setenv("LD_PRELOAD", line, TRUE); + setenv("LD_BIND_NOW", "true", TRUE); + + snprintf(line,sizeof(line)-1,"%s/smbwrapper.32.so", libd); + + if (stat(line, &statbuf) == 0 && S_ISREG(statbuf.st_mode)) { + snprintf(line, sizeof(line)-1, + "%s/smbwrapper.32.so:DEFAULT", libd); + setenv("_RLD_LIST", line, TRUE); + snprintf(line, sizeof(line)-1, + "%s/smbwrapper.so:DEFAULT", libd); + setenv("_RLDN32_LIST", line, TRUE); + } else { + snprintf(line,sizeof(line)-1,"%s/smbwrapper.so:DEFAULT", libd); + setenv("_RLD_LIST", line, TRUE); + } + + if (optind < argc) { + execvp(argv[optind], &argv[optind]); + } else { + char *shellpath = getenv("SHELL"); + + setenv("PS1", "smbsh$ ", TRUE); + + if(shellpath) { + execl(shellpath,"smbsh", NULL); + } else { + setenv("SHELL", "/bin/sh", TRUE); + execl("/bin/sh", "smbsh", NULL); + } + } + printf("launch failed!\n"); + return 1; +} diff --git a/examples/libsmbclient/smbwrapper/smbw.c b/examples/libsmbclient/smbwrapper/smbw.c new file mode 100644 index 0000000000..e2e44c1f0f --- /dev/null +++ b/examples/libsmbclient/smbwrapper/smbw.c @@ -0,0 +1,928 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB wrapper functions + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Derrell Lipman 2003-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/>. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdarg.h> +#include <assert.h> +#include "smbw.h" +#include "bsd-strlfunc.h" + +typedef enum StartupType +{ + StartupType_Fake, + StartupType_Real +} StartupType; + +int smbw_fd_map[__FD_SETSIZE]; +int smbw_ref_count[__FD_SETSIZE]; +char smbw_cwd[PATH_MAX]; +char smbw_prefix[] = SMBW_PREFIX; + +/* needs to be here because of dumb include files on some systems */ +int creat_bits = O_WRONLY|O_CREAT|O_TRUNC; + +int smbw_initialized = 0; + +static int debug_level = 0; + +static SMBCCTX *smbw_ctx; + +extern int smbw_debug; + + +/***************************************************** +smbw_ref -- manipulate reference counts +******************************************************/ +int smbw_ref(int client_fd, Ref_Count_Type type, ...) +{ + va_list ap; + + /* client id values begin at SMBC_BASE_FC. */ + client_fd -= SMBC_BASE_FD; + + va_start(ap, type); + switch(type) + { + case SMBW_RCT_Increment: + return ++smbw_ref_count[client_fd]; + + case SMBW_RCT_Decrement: + return --smbw_ref_count[client_fd]; + + case SMBW_RCT_Get: + return smbw_ref_count[client_fd]; + + case SMBW_RCT_Set: + return (smbw_ref_count[client_fd] = va_arg(ap, int)); + } + va_end(ap); + + /* never gets here */ + return -1; +} + + +/* + * Return a username and password given a server and share name + * + * Returns 0 upon success; + * non-zero otherwise, and errno is set to indicate the error. + */ +static void get_envvar_auth_data(const char *srv, + const char *shr, + char *wg, int wglen, + char *un, int unlen, + char *pw, int pwlen) +{ + char *u; + char *p; + char *w; + + /* Fall back to environment variables */ + + w = getenv("WORKGROUP"); + if (w == NULL) w = ""; + + u = getenv("USER"); + if (u == NULL) u = ""; + + p = getenv("PASSWORD"); + if (p == NULL) p = ""; + + smbw_strlcpy(wg, w, wglen); + smbw_strlcpy(un, u, unlen); + smbw_strlcpy(pw, p, pwlen); +} + +static smbc_get_auth_data_fn get_auth_data_fn = get_envvar_auth_data; + +/***************************************************** +set the get auth data function +******************************************************/ +void smbw_set_auth_data_fn(smbc_get_auth_data_fn fn) +{ + get_auth_data_fn = fn; +} + + +/***************************************************** +ensure that all connections are terminated upon exit +******************************************************/ +static void do_shutdown(void) +{ + if (smbw_ctx != NULL) { + smbc_free_context(smbw_ctx, 1); + } +} + + +/***************************************************** +initialise structures +*******************************************************/ +static void do_init(StartupType startupType) +{ + int i; + char *p; + + smbw_initialized = 1; /* this must be first to avoid recursion! */ + + smbw_ctx = NULL; /* don't free context until it's established */ + + /* initially, no file descriptors are mapped */ + for (i = 0; i < __FD_SETSIZE; i++) { + smbw_fd_map[i] = -1; + smbw_ref_count[i] = 0; + } + + /* See if we've been told to start in a particular directory */ + if ((p=getenv("SMBW_DIR")) != NULL) { + smbw_strlcpy(smbw_cwd, p, PATH_MAX); + + /* we don't want the old directory to be busy */ + (* smbw_libc.chdir)("/"); + + } else { + *smbw_cwd = '\0'; + } + + if ((p=getenv("DEBUG"))) { + debug_level = atoi(p); + } + + if ((smbw_ctx = smbc_new_context()) == NULL) { + fprintf(stderr, "Could not create a context.\n"); + exit(1); + } + + smbc_setDebug(smbw_ctx, debug_level); + smbc_setFunctionAuthData(smbw_ctx, get_auth_data_fn); + smbc_setOptionBrowseMaxLmbCount(smbw_ctx, 0); + smbc_setOptionUrlEncodeReaddirEntries(smbw_ctx, 1); + smbc_setOptionOneSharePerServer(smbw_ctx, 1); + + if (smbc_init_context(smbw_ctx) == NULL) { + fprintf(stderr, "Could not initialize context.\n"); + exit(1); + } + + smbc_set_context(smbw_ctx); + + /* if not real startup, exit handler has already been established */ + if (startupType == StartupType_Real) { + atexit(do_shutdown); + } +} + +/***************************************************** +initialise structures, real start up vs a fork() +*******************************************************/ +void smbw_init(void) +{ + do_init(StartupType_Real); +} + + +/***************************************************** +determine if a file descriptor is a smb one +*******************************************************/ +int smbw_fd(int smbw_fd) +{ + SMBW_INIT(); + + return (smbw_fd >= 0 && + smbw_fd < __FD_SETSIZE && + smbw_fd_map[smbw_fd] >= SMBC_BASE_FD); /* minimum smbc_ fd */ +} + + +/***************************************************** +determine if a path is a smb one +*******************************************************/ +int smbw_path(const char *name) +{ + int len; + int ret; + int saved_errno; + + saved_errno = errno; + + SMBW_INIT(); + + len = strlen(smbw_prefix); + + ret = ((strncmp(name, smbw_prefix, len) == 0 && + (name[len] == '\0' || name[len] == '/')) || + (*name != '/' && *smbw_cwd != '\0')); + + errno = saved_errno; + return ret; +} + + +/***************************************************** +remove redundent stuff from a filename +*******************************************************/ +void smbw_clean_fname(char *name) +{ + char *p, *p2; + int l; + int modified = 1; + + if (!name) return; + + DEBUG(10, ("Clean [%s]...\n", name)); + + while (modified) { + modified = 0; + + if ((p=strstr(name,"/./"))) { + modified = 1; + while (*p) { + p[0] = p[2]; + p++; + } + DEBUG(10, ("\tclean 1 (/./) produced [%s]\n", name)); + } + + if ((p=strstr(name,"//"))) { + modified = 1; + while (*p) { + p[0] = p[1]; + p++; + } + DEBUG(10, ("\tclean 2 (//) produced [%s]\n", name)); + } + + if (strcmp(name,"/../")==0) { + modified = 1; + name[1] = 0; + DEBUG(10,("\tclean 3 (^/../$) produced [%s]\n", name)); + } + + if ((p=strstr(name,"/../"))) { + modified = 1; + for (p2 = (p > name ? p-1 : p); p2 > name; p2--) { + if (p2[0] == '/') break; + } + if (p2 > name) p2++; + while (*p2) { + p2[0] = p[3]; + p2++; + p++; + } + DEBUG(10, ("\tclean 4 (/../) produced [%s]\n", name)); + } + + if (strcmp(name,"/..")==0) { + modified = 1; + name[1] = 0; + DEBUG(10, ("\tclean 5 (^/..$) produced [%s]\n", name)); + } + + l = strlen(name); + p = l>=3?(name+l-3):name; + if (strcmp(p,"/..")==0) { + modified = 1; + for (p2=p-1;p2>name;p2--) { + if (p2[0] == '/') break; + } + if (p2==name) { + p[0] = '/'; + p[1] = 0; + } else { + p2[0] = 0; + } + DEBUG(10, ("\tclean 6 (/..) produced [%s]\n", name)); + } + + l = strlen(name); + p = l>=2?(name+l-2):name; + if (strcmp(p,"/.")==0) { + modified = 1; + if (p == name) { + p[1] = 0; + } else { + p[0] = 0; + } + DEBUG(10, ("\tclean 7 (/.) produced [%s]\n", name)); + } + + if (strncmp(p=name,"./",2) == 0) { + modified = 1; + do { + p[0] = p[2]; + } while (*p++); + DEBUG(10, ("\tclean 8 (^./) produced [%s]\n", name)); + } + + l = strlen(p=name); + if (l > 1 && p[l-1] == '/') { + modified = 1; + p[l-1] = 0; + DEBUG(10, ("\tclean 9 (/) produced [%s]\n", name)); + } + } +} + +void smbw_fix_path(const char *src, char *dest) +{ + const char *p; + int len = strlen(smbw_prefix); + + if (*src == '/') { + for (p = src + len; *p == '/'; p++) + ; + snprintf(dest, PATH_MAX, "smb://%s", p); + } else { + snprintf(dest, PATH_MAX, "%s/%s", smbw_cwd, src); + } + + smbw_clean_fname(dest + 5); + + DEBUG(10, ("smbw_fix_path(%s) returning [%s]\n", src, dest)); +} + + + +/***************************************************** +a wrapper for open() +*******************************************************/ +int smbw_open(const char *fname, int flags, mode_t mode) +{ + int client_fd; + int smbw_fd; + char path[PATH_MAX]; + + SMBW_INIT(); + + if (!fname) { + errno = EINVAL; + return -1; + } + + smbw_fd = (smbw_libc.open)(SMBW_DUMMY, O_WRONLY, 0200); + if (smbw_fd == -1) { + errno = EMFILE; + return -1; + } + + smbw_fix_path(fname, path); + if (flags == creat_bits) { + client_fd = smbc_creat(path, mode); + } else { + client_fd = smbc_open(path, flags, mode); + } + + if (client_fd < 0) { + (* smbw_libc.close)(smbw_fd); + return -1; + } + + smbw_fd_map[smbw_fd] = client_fd; + smbw_ref(client_fd, SMBW_RCT_Increment); + return smbw_fd; +} + + +/***************************************************** +a wrapper for pread() + +there should really be an smbc_pread() to avoid the two +lseek()s required in this kludge. +*******************************************************/ +ssize_t smbw_pread(int smbw_fd, void *buf, size_t count, SMBW_OFF_T ofs) +{ + int client_fd; + ssize_t ret; + int saved_errno; + SMBW_OFF_T old_ofs; + + if (count == 0) { + return 0; + } + + client_fd = smbw_fd_map[smbw_fd]; + + if ((old_ofs = smbc_lseek(client_fd, 0, SEEK_CUR)) < 0 || + smbc_lseek(client_fd, ofs, SEEK_SET) < 0) { + return -1; + } + + if ((ret = smbc_read(client_fd, buf, count)) < 0) { + saved_errno = errno; + (void) smbc_lseek(client_fd, old_ofs, SEEK_SET); + errno = saved_errno; + return -1; + } + + return ret; +} + +/***************************************************** +a wrapper for read() +*******************************************************/ +ssize_t smbw_read(int smbw_fd, void *buf, size_t count) +{ + int client_fd; + + client_fd = smbw_fd_map[smbw_fd]; + + return smbc_read(client_fd, buf, count); +} + + + +/***************************************************** +a wrapper for write() +*******************************************************/ +ssize_t smbw_write(int smbw_fd, void *buf, size_t count) +{ + int client_fd; + + client_fd = smbw_fd_map[smbw_fd]; + + return smbc_write(client_fd, buf, count); +} + +/***************************************************** +a wrapper for pwrite() +*******************************************************/ +ssize_t smbw_pwrite(int smbw_fd, void *buf, size_t count, SMBW_OFF_T ofs) +{ + int saved_errno; + int client_fd; + ssize_t ret; + SMBW_OFF_T old_ofs; + + if (count == 0) { + return 0; + } + + client_fd = smbw_fd_map[smbw_fd]; + + if ((old_ofs = smbc_lseek(client_fd, 0, SEEK_CUR)) < 0 || + smbc_lseek(client_fd, ofs, SEEK_SET) < 0) { + return -1; + } + + if ((ret = smbc_write(client_fd, buf, count)) < 0) { + saved_errno = errno; + (void) smbc_lseek(client_fd, old_ofs, SEEK_SET); + errno = saved_errno; + return -1; + } + + return ret; +} + +/***************************************************** +a wrapper for close() +*******************************************************/ +int smbw_close(int smbw_fd) +{ + int client_fd; + + client_fd = smbw_fd_map[smbw_fd]; + + if (smbw_ref(client_fd, SMBW_RCT_Decrement) > 0) { + return 0; + } + + (* smbw_libc.close)(smbw_fd); + smbw_fd_map[smbw_fd] = -1; + return smbc_close(client_fd); +} + + +/***************************************************** +a wrapper for fcntl() +*******************************************************/ +int smbw_fcntl(int smbw_fd, int cmd, long arg) +{ + return 0; +} + + +/***************************************************** +a wrapper for access() +*******************************************************/ +int smbw_access(const char *name, int mode) +{ + struct SMBW_stat st; + + SMBW_INIT(); + + if (smbw_stat(name, &st)) return -1; + + if (((mode & R_OK) && !(st.s_mode & S_IRUSR)) || + ((mode & W_OK) && !(st.s_mode & S_IWUSR)) || + ((mode & X_OK) && !(st.s_mode & S_IXUSR))) { + errno = EACCES; + return -1; + } + + return 0; +} + +/***************************************************** +a wrapper for readlink() - needed for correct errno setting +*******************************************************/ +int smbw_readlink(const char *fname, char *buf, size_t bufsize) +{ + struct SMBW_stat st; + int ret; + + SMBW_INIT(); + + ret = smbw_stat(fname, &st); + if (ret != 0) { + return -1; + } + + /* it exists - say it isn't a link */ + errno = EINVAL; + return -1; +} + + +/***************************************************** +a wrapper for unlink() +*******************************************************/ +int smbw_unlink(const char *fname) +{ + char path[PATH_MAX]; + + SMBW_INIT(); + + smbw_fix_path(fname, path); + return smbc_unlink(path); +} + + +/***************************************************** +a wrapper for rename() +*******************************************************/ +int smbw_rename(const char *oldname, const char *newname) +{ + char path_old[PATH_MAX]; + char path_new[PATH_MAX]; + + SMBW_INIT(); + + smbw_fix_path(oldname, path_old); + smbw_fix_path(newname, path_new); + return smbc_rename(path_old, path_new); +} + + +/***************************************************** +a wrapper for utimes +*******************************************************/ +int smbw_utimes(const char *fname, void *buf) +{ + char path[PATH_MAX]; + + smbw_fix_path(fname, path); + return smbc_utimes(path, buf); +} + + +/***************************************************** +a wrapper for utime +*******************************************************/ +int smbw_utime(const char *fname, void *buf) +{ + char path[PATH_MAX]; + + smbw_fix_path(fname, path); + return smbc_utime(path, buf); +} + +/***************************************************** +a wrapper for chown() +*******************************************************/ +int smbw_chown(const char *fname, uid_t owner, gid_t group) +{ + /* always indiciate that this is not supported. */ + errno = ENOTSUP; + return -1; +} + +/***************************************************** +a wrapper for chmod() +*******************************************************/ +int smbw_chmod(const char *fname, mode_t newmode) +{ + char path[PATH_MAX]; + + smbw_fix_path(fname, path); + return smbc_chmod(path, newmode); +} + + +/***************************************************** +a wrapper for lseek() +*******************************************************/ +SMBW_OFF_T smbw_lseek(int smbw_fd, + SMBW_OFF_T offset, + int whence) +{ + int client_fd; + SMBW_OFF_T ret; + + client_fd = smbw_fd_map[smbw_fd]; + + ret = smbc_lseek(client_fd, offset, whence); + if (smbw_debug) + { + printf("smbw_lseek(%d/%d, 0x%llx) returned 0x%llx\n", + smbw_fd, client_fd, + (unsigned long long) offset, + (unsigned long long) ret); + } + return ret; +} + +/***************************************************** +a wrapper for dup() +*******************************************************/ +int smbw_dup(int smbw_fd) +{ + int fd2; + + fd2 = (smbw_libc.dup)(smbw_fd); + if (fd2 == -1) { + return -1; + } + + smbw_fd_map[fd2] = smbw_fd_map[smbw_fd]; + smbw_ref(smbw_fd_map[smbw_fd], SMBW_RCT_Increment); + return fd2; +} + + +/***************************************************** +a wrapper for dup2() +*******************************************************/ +int smbw_dup2(int smbw_fd, int fd2) +{ + if ((* smbw_libc.dup2)(smbw_fd, fd2) != fd2) { + return -1; + } + + smbw_fd_map[fd2] = smbw_fd_map[smbw_fd]; + smbw_ref(smbw_fd_map[smbw_fd], SMBW_RCT_Increment); + return fd2; +} + + +/***************************************************** +when we fork we have to close all connections and files +in the child +*******************************************************/ +int smbw_fork(void) +{ + int i; + pid_t child_pid; + int p[2]; + char c = 0; + + SMBW_INIT(); + + if (pipe(p)) return (* smbw_libc.fork)(); + + child_pid = (* smbw_libc.fork)(); + + if (child_pid) { + /* block the parent for a moment until the sockets are + closed */ + (* smbw_libc.close)(p[1]); + (* smbw_libc.read)(p[0], &c, 1); + (* smbw_libc.close)(p[0]); + return child_pid; + } + + (* smbw_libc.close)(p[0]); + + /* close all server connections and locally-opened files */ + for (i = 0; i < __FD_SETSIZE; i++) { + if (smbw_fd_map[i] > 0 && + smbw_ref(smbw_fd_map[i], SMBW_RCT_Get) > 0) { + + smbc_close(smbw_fd_map[i]); + smbw_ref(smbw_fd_map[i], SMBW_RCT_Set, 0); + (* smbw_libc.close)(i); + } + + smbw_fd_map[i] = -1; + } + + /* unblock the parent */ + write(p[1], &c, 1); + (* smbw_libc.close)(p[1]); + + /* specify directory to start in, if it's simulated smb */ + if (*smbw_cwd != '\0') { + setenv("SMBW_DIR", smbw_cwd, 1); + } else { + unsetenv("SMBW_DIR"); + } + + /* Re-initialize this library for the child */ + do_init(StartupType_Fake); + + /* and continue in the child */ + return 0; +} + +int smbw_setxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags) +{ + char path[PATH_MAX]; + + if (strcmp(name, "system.posix_acl_access") == 0) + { + name = "system.*"; + } + + smbw_fix_path(fname, path); + return smbc_setxattr(path, name, value, size, flags); +} + +int smbw_lsetxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags) +{ + char path[PATH_MAX]; + + if (strcmp(name, "system.posix_acl_access") == 0) + { + name = "system.*"; + } + + smbw_fix_path(fname, path); + return smbc_lsetxattr(path, name, value, size, flags); +} + +int smbw_fsetxattr(int smbw_fd, + const char *name, + const void *value, + size_t size, + int flags) +{ + int client_fd; + + if (strcmp(name, "system.posix_acl_access") == 0) + { + name = "system.*"; + } + + client_fd = smbw_fd_map[smbw_fd]; + return smbc_fsetxattr(client_fd, name, value, size, flags); +} + +int smbw_getxattr(const char *fname, + const char *name, + const void *value, + size_t size) +{ + char path[PATH_MAX]; + + if (strcmp(name, "system.posix_acl_access") == 0) + { + name = "system.*"; + } + + smbw_fix_path(fname, path); + + return smbc_getxattr(path, name, value, size); +} + +int smbw_lgetxattr(const char *fname, + const char *name, + const void *value, + size_t size) +{ + char path[PATH_MAX]; + + if (strcmp(name, "system.posix_acl_access") == 0) + { + name = "system.*"; + } + + smbw_fix_path(fname, path); + return smbc_lgetxattr(path, name, value, size); +} + +int smbw_fgetxattr(int smbw_fd, + const char *name, + const void *value, + size_t size) +{ + int client_fd; + + if (strcmp(name, "system.posix_acl_access") == 0) + { + name = "system.*"; + } + + client_fd = smbw_fd_map[smbw_fd]; + return smbc_fgetxattr(client_fd, name, value, size); +} + +int smbw_removexattr(const char *fname, + const char *name) +{ + char path[PATH_MAX]; + + if (strcmp(name, "system.posix_acl_access") == 0) + { + name = "system.*"; + } + + smbw_fix_path(fname, path); + return smbc_removexattr(path, name); +} + +int smbw_lremovexattr(const char *fname, + const char *name) +{ + char path[PATH_MAX]; + + if (strcmp(name, "system.posix_acl_access") == 0) + { + name = "system.*"; + } + + smbw_fix_path(fname, path); + return smbc_lremovexattr(path, name); +} + +int smbw_fremovexattr(int smbw_fd, + const char *name) +{ + int client_fd; + + if (strcmp(name, "system.posix_acl_access") == 0) + { + name = "system.*"; + } + + client_fd = smbw_fd_map[smbw_fd]; + return smbc_fremovexattr(client_fd, name); +} + +int smbw_listxattr(const char *fname, + char *list, + size_t size) +{ + char path[PATH_MAX]; + + smbw_fix_path(fname, path); + return smbc_listxattr(path, list, size); +} + +int smbw_llistxattr(const char *fname, + char *list, + size_t size) +{ + char path[PATH_MAX]; + + smbw_fix_path(fname, path); + return smbc_llistxattr(path, list, size); +} + +int smbw_flistxattr(int smbw_fd, + char *list, + size_t size) +{ + int client_fd; + + client_fd = smbw_fd_map[smbw_fd]; + return smbc_flistxattr(client_fd, list, size); +} diff --git a/examples/libsmbclient/smbwrapper/smbw.h b/examples/libsmbclient/smbwrapper/smbw.h new file mode 100644 index 0000000000..8bf1809ec9 --- /dev/null +++ b/examples/libsmbclient/smbwrapper/smbw.h @@ -0,0 +1,166 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB wrapper functions - definitions + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Derrell Lipman 2003-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/>. +*/ + +#ifndef _SMBW_H +#define _SMBW_H + +#include <sys/types.h> +#include <errno.h> +#include <malloc.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "config.h" /* must come before libsmbclient.h */ +#include "libsmbclient.h" +#include "wrapper.h" + +#ifndef __restrict +# define __restrict +#endif + +#undef DEBUG +#define DEBUG(level, s) do { if (level <= debug_level) printf s; } while (0) + + +#define SMBW_PREFIX "/smb" +#define SMBW_DUMMY "/dev/null" + +extern int smbw_initialized; +#define SMBW_INIT() do { if (! smbw_initialized) smbw_init(); } while (0) + +#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) +# define SMBW_OFF_T off64_t +#else +# define SMBW_OFF_T off_t +#endif + + +/* The following definitions come from smbwrapper/smbw.c */ + +typedef enum { + SMBW_RCT_Increment, + SMBW_RCT_Decrement, + SMBW_RCT_Get, + SMBW_RCT_Set +} Ref_Count_Type; + +int smbw_ref(int client_fd, Ref_Count_Type type, ...); +void smbw_init(void); +int smbw_fd(int fd); +int smbw_path(const char *path); +void smbw_clean_fname(char *name); +void smbw_fix_path(const char *src, char *dest); +void smbw_set_auth_data_fn(smbc_get_auth_data_fn fn); +int smbw_open(const char *fname, int flags, mode_t mode); +ssize_t smbw_pread(int fd, void *buf, size_t count, SMBW_OFF_T ofs); +ssize_t smbw_read(int fd, void *buf, size_t count); +ssize_t smbw_write(int fd, void *buf, size_t count); +ssize_t smbw_pwrite(int fd, void *buf, size_t count, SMBW_OFF_T ofs); +int smbw_close(int fd); +int smbw_fcntl(int fd, int cmd, long arg); +int smbw_access(const char *name, int mode); +int smbw_readlink(const char *path, char *buf, size_t bufsize); +int smbw_unlink(const char *fname); +int smbw_rename(const char *oldname, const char *newname); +int smbw_utime(const char *fname, void *buf); +int smbw_utimes(const char *fname, void *buf); +int smbw_chown(const char *fname, uid_t owner, gid_t group); +int smbw_chmod(const char *fname, mode_t newmode); +SMBW_OFF_T smbw_lseek(int smbw_fd, SMBW_OFF_T offset, int whence); +int smbw_dup(int fd); +int smbw_dup2(int fd, int fd2); +int smbw_fork(void); + +/* The following definitions come from smbwrapper/smbw_dir.c */ + +int smbw_dirp(DIR * dirp); +int smbw_dir_open(const char *fname); +int smbw_dir_fstat(int fd, SMBW_stat *st); +int smbw_dir_close(int fd); +int smbw_getdents(unsigned int fd, SMBW_dirent *dirp, int count); +int smbw_chdir(const char *name); +int smbw_mkdir(const char *fname, mode_t mode); +int smbw_rmdir(const char *fname); +char *smbw_getcwd(char *buf, size_t size); +int smbw_fchdir(int fd); +DIR *smbw_opendir(const char *fname); +SMBW_dirent *smbw_readdir(DIR *dirp); +int smbw_readdir_r(DIR *dirp, + struct SMBW_dirent *__restrict entry, + struct SMBW_dirent **__restrict result); +int smbw_closedir(DIR *dirp); +void smbw_seekdir(DIR *dirp, long long offset); +long long smbw_telldir(DIR *dirp); +int smbw_setxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags); +int smbw_lsetxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags); +int smbw_fsetxattr(int smbw_fd, + const char *name, + const void *value, + size_t size, + int flags); +int smbw_getxattr(const char *fname, + const char *name, + const void *value, + size_t size); +int smbw_lgetxattr(const char *fname, + const char *name, + const void *value, + size_t size); +int smbw_fgetxattr(int smbw_fd, + const char *name, + const void *value, + size_t size); +int smbw_removexattr(const char *fname, + const char *name); +int smbw_lremovexattr(const char *fname, + const char *name); +int smbw_fremovexattr(int smbw_fd, + const char *name); +int smbw_listxattr(const char *fname, + char *list, + size_t size); +int smbw_llistxattr(const char *fname, + char *list, + size_t size); +int smbw_flistxattr(int smbw_fd, + char *list, + size_t size); + +/* The following definitions come from smbwrapper/smbw_stat.c */ + +int smbw_fstat(int fd, SMBW_stat *st); +int smbw_stat(const char *fname, SMBW_stat *st); + +/* The following definitions come from smbwrapper/cache.c */ +int +smbw_cache_functions(SMBCCTX * context); + + +#endif /* _SMBW_H */ diff --git a/examples/libsmbclient/smbwrapper/smbw_dir.c b/examples/libsmbclient/smbwrapper/smbw_dir.c new file mode 100644 index 0000000000..6e473bf0a3 --- /dev/null +++ b/examples/libsmbclient/smbwrapper/smbw_dir.c @@ -0,0 +1,355 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB wrapper directory functions + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Derrell Lipman 2003-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/>. +*/ + +#include "smbw.h" +#include "bsd-strlfunc.h" + +/***************************************************** +determine if a directory handle is a smb one +*******************************************************/ +int smbw_dirp(DIR * dirp) +{ + return ((char *) dirp >= (char *) smbw_fd_map && + (char *) dirp < (char *) &smbw_fd_map[__FD_SETSIZE] && + *(int *) dirp != -1); +} + + +/***************************************************** +a wrapper for getdents() +*******************************************************/ +int smbw_getdents(unsigned int fd_smbw, + struct SMBW_dirent *dirent_external, + int count) +{ + int remaining; + int fd_client = smbw_fd_map[fd_smbw]; + struct smbc_dirent *dirent_internal; + + + for (remaining = count; + remaining > sizeof(struct SMBW_dirent); + dirent_external++) { + + /* + * We do these one at a time because there's otherwise no way + * to limit how many smbc_getdents() will return for us, and + * if it returns too many, it also doesn't give us offsets to + * be able to seek back to where we need to be. In practice, + * this one-at-a-time retrieval isn't a problem because the + * time-consuming network transaction is all done at + * smbc_opendir() time. + */ + dirent_internal = smbc_readdir(fd_client); + if (dirent_internal == NULL) { + break; + } + + remaining -= sizeof(struct SMBW_dirent); + + dirent_external->d_ino = -1; /* not supported */ + dirent_external->d_off = smbc_telldir(fd_client); + dirent_external->d_reclen = sizeof(struct SMBW_dirent); + dirent_external->d_type = dirent_internal->smbc_type; + + smbw_strlcpy(dirent_external->d_name, + dirent_internal->name, + sizeof(dirent_external->d_name) - 1); + smbw_strlcpy(dirent_external->d_comment, + dirent_internal->comment, + sizeof(dirent_external->d_comment) - 1); + } + + return(count - remaining); +} + + +/***************************************************** +a wrapper for chdir() +*******************************************************/ +int smbw_chdir(const char *name) +{ + int simulate; + struct stat statbuf; + char path[PATH_MAX]; + char *p; + + SMBW_INIT(); + + if (!name) { + errno = EINVAL; + return -1; + } + + if (! smbw_path((char *) name)) { + if ((* smbw_libc.chdir)(name) == 0) { + *smbw_cwd = '\0'; + return 0; + } + + return -1; + } + + smbw_fix_path(name, path); + + /* ensure it exists */ + p = path + 6; /* look just past smb:// */ + simulate = (strchr(p, '/') == NULL); + + /* special case for full-network scan, workgroups, and servers */ + if (! simulate) { + + if (smbc_stat(path, &statbuf) < 0) { + return -1; + } + + /* ensure it's a directory */ + if (! S_ISDIR(statbuf.st_mode)) { + errno = ENOTDIR; + return -1; + } + } + + smbw_strlcpy(smbw_cwd, path, PATH_MAX); + + /* we don't want the old directory to be busy */ + (* smbw_libc.chdir)("/"); + + return 0; +} + + +/***************************************************** +a wrapper for mkdir() +*******************************************************/ +int smbw_mkdir(const char *fname, mode_t mode) +{ + char path[PATH_MAX]; + + if (!fname) { + errno = EINVAL; + return -1; + } + + SMBW_INIT(); + + smbw_fix_path(fname, path); + return smbc_mkdir(path, mode); +} + +/***************************************************** +a wrapper for rmdir() +*******************************************************/ +int smbw_rmdir(const char *fname) +{ + char path[PATH_MAX]; + + if (!fname) { + errno = EINVAL; + return -1; + } + + SMBW_INIT(); + + smbw_fix_path(fname, path); + return smbc_rmdir(path); +} + + +/***************************************************** +a wrapper for getcwd() +*******************************************************/ +char *smbw_getcwd(char *buf, size_t size) +{ + SMBW_INIT(); + + if (*smbw_cwd == '\0') { + return (* smbw_libc.getcwd)(buf, size); + } + + if (buf == NULL) { + if (size == 0) { + size = strlen(smbw_cwd) + 1; + } + buf = malloc(size); + if (buf == NULL) { + errno = ENOMEM; + return NULL; + } + } + + smbw_strlcpy(buf, smbw_cwd, size); + buf[size-1] = '\0'; + return buf; +} + +/***************************************************** +a wrapper for fchdir() +*******************************************************/ +int smbw_fchdir(int fd_smbw) +{ + int ret; + + SMBW_INIT(); + + if (! smbw_fd(fd_smbw)) { + ret = (* smbw_libc.fchdir)(fd_smbw); + (void) (* smbw_libc.getcwd)(smbw_cwd, PATH_MAX); + return ret; + } + + errno = EACCES; + return -1; +} + +/***************************************************** +open a directory on the server +*******************************************************/ +DIR *smbw_opendir(const char *fname) +{ + int fd_client; + int fd_smbw; + char path[PATH_MAX]; + DIR * dirp; + + SMBW_INIT(); + + if (!fname) { + errno = EINVAL; + return NULL; + } + + fd_smbw = (smbw_libc.open)(SMBW_DUMMY, O_WRONLY, 0200); + if (fd_smbw == -1) { + errno = EMFILE; + return NULL; + } + + smbw_fix_path(fname, path); + fd_client = smbc_opendir(path); + + if (fd_client < 0) { + (* smbw_libc.close)(fd_smbw); + return NULL; + } + + smbw_fd_map[fd_smbw] = fd_client; + smbw_ref(fd_client, SMBW_RCT_Increment); + dirp = (DIR *) &smbw_fd_map[fd_smbw]; + return dirp; +} + +/***************************************************** +read one entry from a directory +*******************************************************/ +struct SMBW_dirent *smbw_readdir(DIR *dirp) +{ + int fd_smbw; + int fd_client; + struct smbc_dirent *dirent_internal; + static struct SMBW_dirent dirent_external; + + fd_smbw = (int *) dirp - smbw_fd_map; + fd_client = smbw_fd_map[fd_smbw]; + + if ((dirent_internal = smbc_readdir(fd_client)) == NULL) { + return NULL; + } + + dirent_external.d_ino = -1; /* not supported */ + dirent_external.d_off = smbc_telldir(fd_client); + dirent_external.d_reclen = sizeof(struct SMBW_dirent); + dirent_external.d_type = dirent_internal->smbc_type; + smbw_strlcpy(dirent_external.d_name, + dirent_internal->name, + sizeof(dirent_external.d_name) - 1); + smbw_strlcpy(dirent_external.d_comment, + dirent_internal->comment, + sizeof(dirent_external.d_comment) - 1); + + return &dirent_external; +} + +/***************************************************** +read one entry from a directory in a reentrant fashion +ha! samba is not re-entrant, and neither is the +libsmbclient library +*******************************************************/ +int smbw_readdir_r(DIR *dirp, + struct SMBW_dirent *__restrict entry, + struct SMBW_dirent **__restrict result) +{ + SMBW_dirent *dirent; + + dirent = smbw_readdir(dirp); + + if (dirent != NULL) { + *entry = *dirent; + if (result != NULL) { + *result = entry; + } + return 0; + } + + if (result != NULL) { + *result = NULL; + } + return EBADF; +} + + +/***************************************************** +close a DIR* +*******************************************************/ +int smbw_closedir(DIR *dirp) +{ + int fd_smbw = (int *) dirp - smbw_fd_map; + int fd_client = smbw_fd_map[fd_smbw]; + + (* smbw_libc.close)(fd_smbw); + if (smbw_ref(fd_client, SMBW_RCT_Decrement) > 0) { + return 0; + } + smbw_fd_map[fd_smbw] = -1; + return smbc_closedir(fd_client); +} + +/***************************************************** +seek in a directory +*******************************************************/ +void smbw_seekdir(DIR *dirp, long long offset) +{ + int fd_smbw = (int *) dirp - smbw_fd_map; + int fd_client = smbw_fd_map[fd_smbw]; + + smbc_lseekdir(fd_client, offset); +} + +/***************************************************** +current loc in a directory +*******************************************************/ +long long smbw_telldir(DIR *dirp) +{ + int fd_smbw = (int *) dirp - smbw_fd_map; + int fd_client = smbw_fd_map[fd_smbw]; + + return (long long) smbc_telldir(fd_client); +} diff --git a/examples/libsmbclient/smbwrapper/smbw_stat.c b/examples/libsmbclient/smbwrapper/smbw_stat.c new file mode 100644 index 0000000000..7b2b011282 --- /dev/null +++ b/examples/libsmbclient/smbwrapper/smbw_stat.c @@ -0,0 +1,100 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB wrapper stat functions + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Derrell Lipman 2003-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/>. +*/ + +#include "smbw.h" + +static void copy_stat(struct SMBW_stat *external, struct stat *internal) +{ + external->s_dev = internal->st_dev; + external->s_ino = internal->st_ino; + external->s_mode = internal->st_mode; + external->s_nlink = internal->st_nlink; + external->s_uid = internal->st_uid; + external->s_gid = internal->st_gid; + external->s_rdev = internal->st_rdev; + external->s_size = internal->st_size; + external->s_blksize = internal->st_blksize; + external->s_blocks = internal->st_blocks; + external->s_atime = internal->st_atime; + external->s_mtime = internal->st_mtime; + external->s_ctime = internal->st_ctime; +} + + +/***************************************************** +a wrapper for fstat() +*******************************************************/ +int smbw_fstat(int fd_smbw, struct SMBW_stat *st) +{ + int fd_client = smbw_fd_map[fd_smbw]; + struct stat statbuf; + + if (smbc_fstat(fd_client, &statbuf) < 0) { + return -1; + } + + copy_stat(st, &statbuf); + + return 0; +} + + +/***************************************************** +a wrapper for stat() +*******************************************************/ +int smbw_stat(const char *fname, struct SMBW_stat *st) +{ + int simulate; + char *p; + char path[PATH_MAX]; + struct stat statbuf; + + SMBW_INIT(); + + smbw_fix_path(fname, path); + + p = path + 6; /* look just past smb:// */ + simulate = (strchr(p, '/') == NULL); + + /* special case for full-network scan, workgroups, and servers */ + if (simulate) { + statbuf.st_dev = 0; + statbuf.st_ino = 0; + statbuf.st_mode = 0040777; + statbuf.st_nlink = 1; + statbuf.st_uid = 0; + statbuf.st_gid = 0; + statbuf.st_rdev = 0; + statbuf.st_size = 0; + statbuf.st_blksize = 1024; + statbuf.st_blocks = 1; + statbuf.st_atime = 0; /* beginning of epoch */ + statbuf.st_mtime = 0; /* beginning of epoch */ + statbuf.st_ctime = 0; /* beginning of epoch */ + + } else if (smbc_stat(path, &statbuf) < 0) { + return -1; + } + + copy_stat(st, &statbuf); + + return 0; +} diff --git a/examples/libsmbclient/smbwrapper/wrapper.c b/examples/libsmbclient/smbwrapper/wrapper.c new file mode 100644 index 0000000000..3811b04356 --- /dev/null +++ b/examples/libsmbclient/smbwrapper/wrapper.c @@ -0,0 +1,1727 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB wrapper functions + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Derrell Lipman 2002-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/>. +*/ + +/* + * This is a rewrite of the original wrapped.c file, using libdl to obtain + * pointers into the C library rather than attempting to find undocumented + * functions in the C library to call for native file access. The problem + * with the original implementation's paradigm is that samba manipulates + * defines such that it gets the sizes of structures that it wants + * (e.g. mapping 32-bit functions to 64-bit functions with their associated + * 64-bit structure fields), but programs run under smbsh or using + * smbwrapper.so were not necessarily compiled with the same flags. As an + * example of the problem, a program calling stat() passes a pointer to a + * "struct stat" but the fields in that structure are different in samba than + * they are in the calling program if the calling program was not compiled to + * force stat() to be mapped to stat64(). + * + * In this version, we provide an interface to each of the native functions, + * not just the ones that samba is compiled to map to. We obtain the function + * pointers from the C library using dlsym(), and for native file operations, + * directly call the same function that the calling application was + * requesting. Since the size of the calling application's structures vary + * depending on what function was called, we use our own internal structures + * for passing information to/from the SMB equivalent functions, and map them + * back to the native structures before returning the result to the caller. + * + * This implementation was completed 25 December 2002. + * Derrell Lipman + */ + +/* We do not want auto munging of 32->64 bit names in this file (only) */ +#undef _FILE_OFFSET_BITS +#undef _GNU_SOURCE + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <utime.h> +#include <stdio.h> +#include <dirent.h> +#include <signal.h> +#include <stdarg.h> +#include <string.h> +#ifdef __USE_GNU +# define SMBW_USE_GNU +#endif +#define __USE_GNU /* need this to have RTLD_NEXT defined */ +#include <dlfcn.h> +#ifndef SMBW_USE_GNU +# undef __USE_GNU +#endif +#include <errno.h> +#include "libsmbclient.h" +#include "bsd-strlfunc.h" +#include "wrapper.h" + +/* + * Debug bits: + * 0x0 = none + * 0x1 = display symbol definitions not found in C library + * 0x2 = show wrapper functions being called + * 0x4 = log to file SMBW_DEBUG_FILE instead of stderr + */ +#define SMBW_DEBUG 0x0 +#define SMBW_DEBUG_FILE "/tmp/smbw.log" + +int smbw_debug = 0; + +#if SMBW_DEBUG & 0x2 +static int debugFd = 2; +#endif + +#ifndef ENOTSUP +#define ENOTSUP EOPNOTSUPP +#endif + +/* + * None of the methods of having the initialization function called + * automatically upon shared library startup are effective in all situations. + * We provide the "-init" parameter to the linker which is effective most of + * the time, but fails for applications that provide their own shared + * libraries with _init() functions (e.g. ps). We can't use "-z initfirst" + * because the environment isn't yet set up at that point, so we can't find + * our shared memory identifier (see shared.c). We therefore must resort to + * this tried-and-true method of keeping an "initialized" flag. We check it + * prior to calling the initialize() function to save a function call (a slow + * operation on x86). + */ +#if SMBW_DEBUG & 0x2 +# define check_init(buf) \ + do { \ + int saved_errno = errno; \ + if (! initialized) initialize(); \ + (* smbw_libc.write)(debugFd, "["buf"]", sizeof(buf)+1); \ + errno = saved_errno; \ + } while (0) +#else +# define check_init(buf) \ + do { \ + if (! initialized) smbw_initialize(); \ + } while (0) +#endif + +static void initialize(void); + +static int initialized = 0; + +SMBW_libc_pointers smbw_libc; + +/* + * A public entry point used by the "-init" option to the linker. + */ +void smbw_initialize(void) +{ + initialize(); +} + +static void initialize(void) +{ + int saved_errno; +#if SMBW_DEBUG & 0x1 + char *error; +#endif + + saved_errno = errno; + + if (initialized) { + return; + } + initialized = 1; + +#if SMBW_DEBUG & 0x1 +# define GETSYM(symname, symstring) \ + if ((smbw_libc.symname = dlsym(RTLD_NEXT, symstring)) == NULL) { \ + if (smbw_libc.write != NULL && \ + (error = dlerror()) != NULL) { \ + (* smbw_libc.write)(1, error, strlen(error)); \ + (* smbw_libc.write)(1, "\n", 1); \ + } \ + } +#else +# define GETSYM(symname, symstring) \ + smbw_libc.symname = dlsym(RTLD_NEXT, symstring); +#endif + + /* + * Get pointers to each of the symbols we'll need, from the C library + * + * Some of these symbols may not be found in the C library. That's + * fine. We declare all of them here, and if the C library supports + * them, they may be called so we have the wrappers for them. If the + * C library doesn't support them, then the wrapper function will + * never be called, and the null pointer will never be dereferenced. + */ + GETSYM(write, "write"); /* first, to allow debugging */ + GETSYM(open, "open"); + GETSYM(_open, "_open"); + GETSYM(__open, "__open"); + GETSYM(open64, "open64"); + GETSYM(_open64, "_open64"); + GETSYM(__open64, "__open64"); + GETSYM(pread, "pread"); + GETSYM(pread64, "pread64"); + GETSYM(pwrite, "pwrite"); + GETSYM(pwrite64, "pwrite64"); + GETSYM(close, "close"); + GETSYM(__close, "__close"); + GETSYM(_close, "_close"); + GETSYM(fcntl, "fcntl"); + GETSYM(__fcntl, "__fcntl"); + GETSYM(_fcntl, "_fcntl"); + GETSYM(getdents, "getdents"); + GETSYM(__getdents, "__getdents"); + GETSYM(_getdents, "_getdents"); + GETSYM(getdents64, "getdents64"); + GETSYM(lseek, "lseek"); + GETSYM(__lseek, "__lseek"); + GETSYM(_lseek, "_lseek"); + GETSYM(lseek64, "lseek64"); + GETSYM(__lseek64, "__lseek64"); + GETSYM(_lseek64, "_lseek64"); + GETSYM(read, "read"); + GETSYM(__read, "__read"); + GETSYM(_read, "_read"); + GETSYM(__write, "__write"); + GETSYM(_write, "_write"); + GETSYM(access, "access"); + GETSYM(chmod, "chmod"); + GETSYM(fchmod, "fchmod"); + GETSYM(chown, "chown"); + GETSYM(fchown, "fchown"); + GETSYM(__xstat, "__xstat"); + GETSYM(getcwd, "getcwd"); + GETSYM(mkdir, "mkdir"); + GETSYM(__fxstat, "__fxstat"); + GETSYM(__lxstat, "__lxstat"); + GETSYM(stat, "stat"); + GETSYM(lstat, "lstat"); + GETSYM(fstat, "fstat"); + GETSYM(unlink, "unlink"); + GETSYM(utime, "utime"); + GETSYM(utimes, "utimes"); + GETSYM(readlink, "readlink"); + GETSYM(rename, "rename"); + GETSYM(rmdir, "rmdir"); + GETSYM(symlink, "symlink"); + GETSYM(dup, "dup"); + GETSYM(dup2, "dup2"); + GETSYM(opendir, "opendir"); + GETSYM(readdir, "readdir"); + GETSYM(closedir, "closedir"); + GETSYM(telldir, "telldir"); + GETSYM(seekdir, "seekdir"); + GETSYM(creat, "creat"); + GETSYM(creat64, "creat64"); + GETSYM(__xstat64, "__xstat64"); + GETSYM(stat64, "stat64"); + GETSYM(__fxstat64, "__fxstat64"); + GETSYM(fstat64, "fstat64"); + GETSYM(__lxstat64, "__lxstat64"); + GETSYM(lstat64, "lstat64"); + GETSYM(_llseek, "_llseek"); + GETSYM(readdir64, "readdir64"); + GETSYM(readdir_r, "readdir_r"); + GETSYM(readdir64_r, "readdir64_r"); + GETSYM(setxattr, "setxattr"); + GETSYM(lsetxattr, "lsetxattr"); + GETSYM(fsetxattr, "fsetxattr"); + GETSYM(getxattr, "getxattr"); + GETSYM(lgetxattr, "lgetxattr"); + GETSYM(fgetxattr, "fgetxattr"); + GETSYM(removexattr, "removexattr"); + GETSYM(lremovexattr, "lremovexattr"); + GETSYM(fremovexattr, "fremovexattr"); + GETSYM(listxattr, "listxattr"); + GETSYM(llistxattr, "llistxattr"); + GETSYM(flistxattr, "flistxattr"); + GETSYM(chdir, "chdir"); + GETSYM(fchdir, "fchdir"); + GETSYM(fork, "fork"); + GETSYM(select, "select"); + GETSYM(_select, "_select"); + GETSYM(__select, "__select"); + +#if SMBW_DEBUG & 4 + { + if ((debugFd = + open(SMBW_DEBUG_FILE, O_WRONLY | O_CREAT | O_APPEND)) < 0) + { +# define SMBW_MESSAGE "Could not create " SMBW_DEBUG_FILE "\n" + (* smbw_libc.write)(1, SMBW_MESSAGE, sizeof(SMBW_MESSAGE)); +# undef SMBW_MESSAGE + exit(1); + } + } +#endif + + errno = saved_errno; +} + +/** + ** Static Functions + **/ + +static void stat_convert(struct SMBW_stat *src, struct stat *dest) +{ + memset(dest, '\0', sizeof(*dest)); + dest->st_size = src->s_size; + dest->st_mode = src->s_mode; + dest->st_ino = src->s_ino; + dest->st_dev = src->s_dev; + dest->st_rdev = src->s_rdev; + dest->st_nlink = src->s_nlink; + dest->st_uid = src->s_uid; + dest->st_gid = src->s_gid; + dest->st_atime = src->s_atime; + dest->st_mtime = src->s_mtime; + dest->st_ctime = src->s_ctime; + dest->st_blksize = src->s_blksize; + dest->st_blocks = src->s_blocks; +} + +static void stat64_convert(struct SMBW_stat *src, struct stat64 *dest) +{ + memset(dest, '\0', sizeof(*dest)); + dest->st_size = src->s_size; + dest->st_mode = src->s_mode; + dest->st_ino = src->s_ino; + dest->st_dev = src->s_dev; + dest->st_rdev = src->s_rdev; + dest->st_nlink = src->s_nlink; + dest->st_uid = src->s_uid; + dest->st_gid = src->s_gid; + dest->st_atime = src->s_atime; + dest->st_mtime = src->s_mtime; + dest->st_ctime = src->s_ctime; + dest->st_blksize = src->s_blksize; + dest->st_blocks = src->s_blocks; +} + +static void dirent_convert(struct SMBW_dirent *src, struct dirent *dest) +{ + char *p; + + memset(dest, '\0', sizeof(*dest)); + dest->d_ino = src->d_ino; + dest->d_off = src->d_off; + + switch(src->d_type) + { + case SMBC_WORKGROUP: + case SMBC_SERVER: + case SMBC_FILE_SHARE: + case SMBC_DIR: + dest->d_type = DT_DIR; + break; + + case SMBC_FILE: + dest->d_type = DT_REG; + break; + + case SMBC_PRINTER_SHARE: + dest->d_type = DT_CHR; + break; + + case SMBC_COMMS_SHARE: + dest->d_type = DT_SOCK; + break; + + case SMBC_IPC_SHARE: + dest->d_type = DT_FIFO; + break; + + case SMBC_LINK: + dest->d_type = DT_LNK; + break; + } + + dest->d_reclen = src->d_reclen; + smbw_strlcpy(dest->d_name, src->d_name, sizeof(dest->d_name)); + p = dest->d_name + strlen(dest->d_name) + 1; + smbw_strlcpy(p, + src->d_comment, + sizeof(dest->d_name) - (p - dest->d_name)); +} + +static void dirent64_convert(struct SMBW_dirent *src, struct dirent64 *dest) +{ + char *p; + + memset(dest, '\0', sizeof(*dest)); + dest->d_ino = src->d_ino; + dest->d_off = src->d_off; + + switch(src->d_type) + { + case SMBC_WORKGROUP: + case SMBC_SERVER: + case SMBC_FILE_SHARE: + case SMBC_DIR: + dest->d_type = DT_DIR; + break; + + case SMBC_FILE: + dest->d_type = DT_REG; + break; + + case SMBC_PRINTER_SHARE: + dest->d_type = DT_CHR; + break; + + case SMBC_COMMS_SHARE: + dest->d_type = DT_SOCK; + break; + + case SMBC_IPC_SHARE: + dest->d_type = DT_FIFO; + break; + + case SMBC_LINK: + dest->d_type = DT_LNK; + break; + } + + dest->d_reclen = src->d_reclen; + smbw_strlcpy(dest->d_name, src->d_name, sizeof(dest->d_name)); + p = dest->d_name + strlen(dest->d_name) + 1; + smbw_strlcpy(p, + src->d_comment, + sizeof(dest->d_name) - (p - dest->d_name)); +} + +static int openx(char *name, int flags, mode_t mode, int (* f)(char *, int, mode_t)) +{ + if (smbw_path(name)) { + return smbw_open(name, flags, mode); + } + + return (* f)(name, flags, mode); +} + +static int closex(int fd, int (* f)(int fd)) +{ + if (smbw_fd(fd)) { + return smbw_close(fd); + } + + return (* f)(fd); +} + +static int fcntlx(int fd, int cmd, long arg, int (* f)(int, int, long)) +{ + if (smbw_fd(fd)) { + return smbw_fcntl(fd, cmd, arg); + } + + return (* f)(fd, cmd, arg); +} + +static int getdentsx(int fd, struct dirent *external, unsigned int count, int (* f)(int, struct dirent *, unsigned int)) +{ + if (smbw_fd(fd)) { + int i; + int internal_count; + struct SMBW_dirent *internal; + int ret; + int n; + + /* + * LIMITATION: If they pass a count which is not a multiple of + * the size of struct dirent, they will not get a partial + * structure; we ignore the excess count. + */ + n = (count / sizeof(struct dirent)); + + internal_count = sizeof(struct SMBW_dirent) * n; + internal = malloc(internal_count); + if (internal == NULL) { + errno = ENOMEM; + return -1; + } + ret = smbw_getdents(fd, internal, internal_count); + if (ret <= 0) + return ret; + + ret = sizeof(struct dirent) * n; + + for (i = 0; i < n; i++) + dirent_convert(&internal[i], &external[i]); + + return ret; + } + + return (* f)(fd, external, count); +} + +static off_t lseekx(int fd, + off_t offset, + int whence, + off_t (* f)(int, off_t, int)) +{ + off_t ret; + + /* + * We have left the definitions of the smbw_ functions undefined, + * because types such as off_t can differ in meaning betweent his + * function and smbw.c et al. Functions that return other than an + * integer value, however, MUST have their return value defined. + */ + off64_t smbw_lseek(); + + if (smbw_fd(fd)) { + return (off_t) smbw_lseek(fd, offset, whence); + } + + ret = (* f)(fd, offset, whence); + if (smbw_debug) + { + printf("lseekx(%d, 0x%llx) returned 0x%llx\n", + fd, + (unsigned long long) offset, + (unsigned long long) ret); + } + return ret; +} + +static off64_t lseek64x(int fd, + off64_t offset, + int whence, + off64_t (* f)(int, off64_t, int)) +{ + off64_t ret; + + /* + * We have left the definitions of the smbw_ functions undefined, + * because types such as off_t can differ in meaning betweent his + * function and smbw.c et al. Functions that return other than an + * integer value, however, MUST have their return value defined. + */ + off64_t smbw_lseek(); + + if (smbw_fd(fd)) + ret = smbw_lseek(fd, offset, whence); + else + ret = (* f)(fd, offset, whence); + if (smbw_debug) + { + printf("lseek64x(%d, 0x%llx) returned 0x%llx\n", + fd, + (unsigned long long) offset, + (unsigned long long) ret); + } + return ret; +} + +static ssize_t readx(int fd, void *buf, size_t count, ssize_t (* f)(int, void *, size_t)) +{ + if (smbw_fd(fd)) { + return smbw_read(fd, buf, count); + } + + return (* f)(fd, buf, count); +} + +static ssize_t writex(int fd, void *buf, size_t count, ssize_t (* f)(int, void *, size_t)) +{ + if (smbw_fd(fd)) { + return smbw_write(fd, buf, count); + } + + return (* f)(fd, buf, count); +} + + +/** + ** Wrapper Functions + **/ + +int open(__const char *name, int flags, ...) +{ + va_list ap; + mode_t mode; + + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + + check_init("open"); + + return openx((char *) name, flags, mode, smbw_libc.open); +} + +int _open(char *name, int flags, mode_t mode) +{ + check_init("open"); + + return openx(name, flags, mode, smbw_libc._open); +} + +int __open(char *name, int flags, mode_t mode) +{ + check_init("open"); + + return openx(name, flags, mode, smbw_libc.__open); +} + +int open64 (__const char *name, int flags, ...) +{ + va_list ap; + mode_t mode; + + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + + check_init("open64"); + return openx((char *) name, flags, mode, smbw_libc.open64); +} + +int _open64(char *name, int flags, mode_t mode) +{ + check_init("_open64"); + return openx(name, flags, mode, smbw_libc._open64); +} + +int __open64(char *name, int flags, mode_t mode) +{ + check_init("__open64"); + return openx(name, flags, mode, smbw_libc.__open64); +} + +ssize_t pread(int fd, void *buf, size_t size, off_t ofs) +{ + check_init("pread"); + + if (smbw_fd(fd)) { + return smbw_pread(fd, buf, size, ofs); + } + + return (* smbw_libc.pread)(fd, buf, size, ofs); +} + +ssize_t pread64(int fd, void *buf, size_t size, off64_t ofs) +{ + check_init("pread64"); + + if (smbw_fd(fd)) { + return smbw_pread(fd, buf, size, (off_t) ofs); + } + + return (* smbw_libc.pread64)(fd, buf, size, ofs); +} + +ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs) +{ + check_init("pwrite"); + + if (smbw_fd(fd)) { + return smbw_pwrite(fd, (void *) buf, size, ofs); + } + + return (* smbw_libc.pwrite)(fd, (void *) buf, size, ofs); +} + +ssize_t pwrite64(int fd, const void *buf, size_t size, off64_t ofs) +{ + check_init("pwrite64"); + + if (smbw_fd(fd)) { + return smbw_pwrite(fd, (void *) buf, size, (off_t) ofs); + } + + return (* smbw_libc.pwrite64)(fd, (void *) buf, size, ofs); +} + +int chdir(const char *name) +{ + check_init("chdir"); + return smbw_chdir((char *) name);; +} + +int __chdir(char *name) +{ + check_init("__chdir"); + return smbw_chdir(name); +} + +int _chdir(char *name) +{ + check_init("_chdir"); + return smbw_chdir(name); +} + +int close(int fd) +{ + check_init("close"); + return closex(fd, smbw_libc.close); +} + +int __close(int fd) +{ + check_init("__close"); + return closex(fd, smbw_libc.__close); +} + +int _close(int fd) +{ + check_init("_close"); + return closex(fd, smbw_libc._close); +} + +int fchdir(int fd) +{ + check_init("fchdir"); + return smbw_fchdir(fd); +} + +int __fchdir(int fd) +{ + check_init("__fchdir"); + return fchdir(fd); +} + +int _fchdir(int fd) +{ + check_init("_fchdir"); + return fchdir(fd); +} + +int fcntl (int fd, int cmd, ...) +{ + va_list ap; + long arg; + + va_start(ap, cmd); + arg = va_arg(ap, long); + va_end(ap); + + check_init("fcntl"); + return fcntlx(fd, cmd, arg, smbw_libc.fcntl); +} + +int __fcntl(int fd, int cmd, ...) +{ + va_list ap; + long arg; + + va_start(ap, cmd); + arg = va_arg(ap, long); + va_end(ap); + + check_init("__fcntl"); + return fcntlx(fd, cmd, arg, smbw_libc.__fcntl); +} + +int _fcntl(int fd, int cmd, ...) +{ + va_list ap; + long arg; + + va_start(ap, cmd); + arg = va_arg(ap, long); + va_end(ap); + + check_init("_fcntl"); + return fcntlx(fd, cmd, arg, smbw_libc._fcntl); +} + +int getdents(int fd, struct dirent *dirp, unsigned int count) +{ + check_init("getdents"); + return getdentsx(fd, dirp, count, smbw_libc.getdents); +} + +int __getdents(int fd, struct dirent *dirp, unsigned int count) +{ + check_init("__getdents"); + return getdentsx(fd, dirp, count, smbw_libc.__getdents); +} + +int _getdents(int fd, struct dirent *dirp, unsigned int count) +{ + check_init("_getdents"); + return getdentsx(fd, dirp, count, smbw_libc._getdents); +} + +int getdents64(int fd, struct dirent64 *external, unsigned int count) +{ + check_init("getdents64"); + if (smbw_fd(fd)) { + int i; + struct SMBW_dirent *internal; + int ret; + int n; + + /* + * LIMITATION: If they pass a count which is not a multiple of + * the size of struct dirent, they will not get a partial + * structure; we ignore the excess count. + */ + n = (count / sizeof(struct dirent64)); + + internal = malloc(sizeof(struct SMBW_dirent) * n); + if (internal == NULL) { + errno = ENOMEM; + return -1; + } + ret = smbw_getdents(fd, internal, count); + if (ret <= 0) + return ret; + + ret = sizeof(struct dirent) * count; + + for (i = 0; count; i++, count--) + dirent64_convert(&internal[i], &external[i]); + + return ret; + } + + return (* smbw_libc.getdents64)(fd, external, count); +} + +off_t lseek(int fd, off_t offset, int whence) +{ + off_t ret; + check_init("lseek"); + ret = lseekx(fd, offset, whence, smbw_libc.lseek); + if (smbw_debug) + { + printf("lseek(%d, 0x%llx) returned 0x%llx\n", + fd, + (unsigned long long) offset, + (unsigned long long) ret); + } + return ret; +} + +off_t __lseek(int fd, off_t offset, int whence) +{ + off_t ret; + check_init("__lseek"); + ret = lseekx(fd, offset, whence, smbw_libc.__lseek); + if (smbw_debug) + { + printf("__lseek(%d, 0x%llx) returned 0x%llx\n", + fd, + (unsigned long long) offset, + (unsigned long long) ret); + } + return ret; +} + +off_t _lseek(int fd, off_t offset, int whence) +{ + off_t ret; + check_init("_lseek"); + ret = lseekx(fd, offset, whence, smbw_libc._lseek); + if (smbw_debug) + { + printf("_lseek(%d, 0x%llx) returned 0x%llx\n", + fd, + (unsigned long long) offset, + (unsigned long long) ret); + } + return ret; +} + +off64_t lseek64(int fd, off64_t offset, int whence) +{ + off64_t ret; + check_init("lseek64"); + ret = lseek64x(fd, offset, whence, smbw_libc.lseek64); + if (smbw_debug) + { + printf("lseek64(%d, 0x%llx) returned 0x%llx\n", + fd, + (unsigned long long) offset, + (unsigned long long) ret); + } + return ret; +} + +off64_t __lseek64(int fd, off64_t offset, int whence) +{ + check_init("__lseek64"); + return lseek64x(fd, offset, whence, smbw_libc.__lseek64); +} + +off64_t _lseek64(int fd, off64_t offset, int whence) +{ + off64_t ret; + check_init("_lseek64"); + ret = lseek64x(fd, offset, whence, smbw_libc._lseek64); + if (smbw_debug) + { + printf("_lseek64(%d, 0x%llx) returned 0x%llx\n", + fd, + (unsigned long long) offset, + (unsigned long long) ret); + } + return ret; +} + +ssize_t read(int fd, void *buf, size_t count) +{ + check_init("read"); + return readx(fd, buf, count, smbw_libc.read); +} + +ssize_t __read(int fd, void *buf, size_t count) +{ + check_init("__read"); + return readx(fd, buf, count, smbw_libc.__read); +} + +ssize_t _read(int fd, void *buf, size_t count) +{ + check_init("_read"); + return readx(fd, buf, count, smbw_libc._read); +} + +ssize_t write(int fd, const void *buf, size_t count) +{ + check_init("write"); + return writex(fd, (void *) buf, count, smbw_libc.write); +} + +ssize_t __write(int fd, const void *buf, size_t count) +{ + check_init("__write"); + return writex(fd, (void *) buf, count, smbw_libc.__write); +} + +ssize_t _write(int fd, const void *buf, size_t count) +{ + check_init("_write"); + return writex(fd, (void *) buf, count, smbw_libc._write); +} + +int access(const char *name, int mode) +{ + check_init("access"); + + if (smbw_path((char *) name)) { + return smbw_access((char *) name, mode); + } + + return (* smbw_libc.access)((char *) name, mode); +} + +int chmod(const char *name, mode_t mode) +{ + check_init("chmod"); + + if (smbw_path((char *) name)) { + return smbw_chmod((char *) name, mode); + } + + return (* smbw_libc.chmod)((char *) name, mode); +} + +int fchmod(int fd, mode_t mode) +{ + check_init("fchmod"); + + if (smbw_fd(fd)) { + /* Not yet implemented in libsmbclient */ + return ENOTSUP; + } + + return (* smbw_libc.fchmod)(fd, mode); +} + +int chown(const char *name, uid_t owner, gid_t group) +{ + check_init("chown"); + + if (smbw_path((char *) name)) { + return smbw_chown((char *) name, owner, group); + } + + return (* smbw_libc.chown)((char *) name, owner, group); +} + +int fchown(int fd, uid_t owner, gid_t group) +{ + check_init("fchown"); + + if (smbw_fd(fd)) { + /* Not yet implemented in libsmbclient */ + return ENOTSUP; + } + + return (* smbw_libc.fchown)(fd, owner, group); +} + +char *getcwd(char *buf, size_t size) +{ + check_init("getcwd"); + return (char *)smbw_getcwd(buf, size); +} + +int mkdir(const char *name, mode_t mode) +{ + check_init("mkdir"); + + if (smbw_path((char *) name)) { + return smbw_mkdir((char *) name, mode); + } + + return (* smbw_libc.mkdir)((char *) name, mode); +} + +int __fxstat(int vers, int fd, struct stat *st) +{ + check_init("__fxstat"); + + if (smbw_fd(fd)) { + struct SMBW_stat statbuf; + int ret = smbw_fstat(fd, &statbuf); + stat_convert(&statbuf, st); + return ret; + } + + return (* smbw_libc.__fxstat)(vers, fd, st); +} + +int __xstat(int vers, const char *name, struct stat *st) +{ + check_init("__xstat"); + + if (smbw_path((char *) name)) { + struct SMBW_stat statbuf; + int ret = smbw_stat((char *) name, &statbuf); + stat_convert(&statbuf, st); + return ret; + } + + return (* smbw_libc.__xstat)(vers, (char *) name, st); +} + +int __lxstat(int vers, const char *name, struct stat *st) +{ + check_init("__lxstat"); + + if (smbw_path((char *) name)) { + struct SMBW_stat statbuf; + int ret = smbw_stat((char *) name, &statbuf); + stat_convert(&statbuf, st); + return ret; + } + + return (* smbw_libc.__lxstat)(vers, (char *) name, st); +} + +int stat(const char *name, struct stat *st) +{ + check_init("stat"); + + if (smbw_path((char *) name)) { + struct SMBW_stat statbuf; + int ret = smbw_stat((char *) name, &statbuf); + stat_convert(&statbuf, st); + return ret; + } + + return (* smbw_libc.stat)((char *) name, st); +} + +int lstat(const char *name, struct stat *st) +{ + check_init("lstat"); + + if (smbw_path((char *) name)) { + struct SMBW_stat statbuf; + int ret = smbw_stat((char *) name, &statbuf); + stat_convert(&statbuf, st); + return ret; + } + + return (* smbw_libc.lstat)((char *) name, st); +} + +int fstat(int fd, struct stat *st) +{ + check_init("fstat"); + + if (smbw_fd(fd)) { + struct SMBW_stat statbuf; + int ret = smbw_fstat(fd, &statbuf); + stat_convert(&statbuf, st); + return ret; + } + + return (* smbw_libc.fstat)(fd, st); +} + +int unlink(const char *name) +{ + check_init("unlink"); + + if (smbw_path((char *) name)) { + return smbw_unlink((char *) name); + } + + return (* smbw_libc.unlink)((char *) name); +} + +int utime(const char *name, const struct utimbuf *tvp) +{ + check_init("utime"); + + if (smbw_path(name)) { + return smbw_utime(name, (struct utimbuf *) tvp); + } + + return (* smbw_libc.utime)((char *) name, (struct utimbuf *) tvp); +} + +int utimes(const char *name, const struct timeval *tvp) +{ + check_init("utimes"); + + if (smbw_path(name)) { + return smbw_utimes(name, (struct timeval *) tvp); + } + + return (* smbw_libc.utimes)((char *) name, (struct timeval *) tvp); +} + +ssize_t readlink(const char *path, char *buf, size_t bufsize) +{ + check_init("readlink"); + + if (smbw_path((char *) path)) { + return smbw_readlink(path, (char *) buf, bufsize); + } + + return (* smbw_libc.readlink)((char *) path, buf, bufsize); +} + +int rename(const char *oldname, const char *newname) +{ + int p1, p2; + + check_init("rename"); + + p1 = smbw_path((char *) oldname); + p2 = smbw_path((char *) newname); + if (p1 ^ p2) { + /* can't cross filesystem boundaries */ + errno = EXDEV; + return -1; + } + if (p1 && p2) { + return smbw_rename((char *) oldname, (char *) newname); + } + + return (* smbw_libc.rename)((char *) oldname, (char *) newname); +} + +int rmdir(const char *name) +{ + check_init("rmdir"); + + if (smbw_path((char *) name)) { + return smbw_rmdir((char *) name); + } + + return (* smbw_libc.rmdir)((char *) name); +} + +int symlink(const char *topath, const char *frompath) +{ + int p1, p2; + + check_init("symlink"); + + p1 = smbw_path((char *) topath); + p2 = smbw_path((char *) frompath); + if (p1 || p2) { + /* can't handle symlinks */ + errno = EPERM; + return -1; + } + + return (* smbw_libc.symlink)((char *) topath, (char *) frompath); +} + +int dup(int fd) +{ + check_init("dup"); + + if (smbw_fd(fd)) { + return smbw_dup(fd); + } + + return (* smbw_libc.dup)(fd); +} + +int dup2(int oldfd, int newfd) +{ + check_init("dup2"); + + if (smbw_fd(newfd)) { + (* smbw_libc.close)(newfd); + } + + if (smbw_fd(oldfd)) { + return smbw_dup2(oldfd, newfd); + } + + return (* smbw_libc.dup2)(oldfd, newfd); +} + + +DIR *opendir(const char *name) +{ + check_init("opendir"); + + if (smbw_path((char *) name)) { + return (void *)smbw_opendir((char *) name); + } + + return (* smbw_libc.opendir)((char *) name); +} + +struct dirent *readdir(DIR *dir) +{ + check_init("readdir"); + + if (smbw_dirp(dir)) { + static struct dirent external; + struct SMBW_dirent * internal = (void *)smbw_readdir(dir); + if (internal != NULL) { + dirent_convert(internal, &external); + return &external; + } + return NULL; + } + return (* smbw_libc.readdir)(dir); +} + +int closedir(DIR *dir) +{ + check_init("closedir"); + + if (smbw_dirp(dir)) { + return smbw_closedir(dir); + } + + return (* smbw_libc.closedir)(dir); +} + +long telldir(DIR *dir) +{ + check_init("telldir"); + + if (smbw_dirp(dir)) { + return (long) smbw_telldir(dir); + } + + return (* smbw_libc.telldir)(dir); +} + +void seekdir(DIR *dir, long offset) +{ + check_init("seekdir"); + + if (smbw_dirp(dir)) { + smbw_seekdir(dir, (long long) offset); + return; + } + + (* smbw_libc.seekdir)(dir, offset); +} + +int creat(const char *path, mode_t mode) +{ + extern int creat_bits; + + check_init("creat"); + return openx((char *) path, creat_bits, mode, smbw_libc.open); +} + +int creat64(const char *path, mode_t mode) +{ + extern int creat_bits; + + check_init("creat64"); + return openx((char *) path, creat_bits, mode, smbw_libc.open64); +} + +int __xstat64 (int ver, const char *name, struct stat64 *st64) +{ + check_init("__xstat64"); + + if (smbw_path((char *) name)) { + struct SMBW_stat statbuf; + int ret = smbw_stat((char *) name, &statbuf); + stat64_convert(&statbuf, st64); + return ret; + } + + return (* smbw_libc.__xstat64)(ver, (char *) name, st64); +} + +int stat64(const char *name, struct stat64 *st64) +{ + check_init("stat64"); + + if (smbw_path((char *) name)) { + struct SMBW_stat statbuf; + int ret = smbw_stat((char *) name, &statbuf); + stat64_convert(&statbuf, st64); + return ret; + } + + return (* smbw_libc.stat64)((char *) name, st64); +} + +int __fxstat64(int ver, int fd, struct stat64 *st64) +{ + check_init("__fxstat64"); + + if (smbw_fd(fd)) { + struct SMBW_stat statbuf; + int ret = smbw_fstat(fd, &statbuf); + stat64_convert(&statbuf, st64); + return ret; + } + + return (* smbw_libc.__fxstat64)(ver, fd, st64); +} + +int fstat64(int fd, struct stat64 *st64) +{ + check_init("fstat64"); + + if (smbw_fd(fd)) { + struct SMBW_stat statbuf; + int ret = smbw_fstat(fd, &statbuf); + stat64_convert(&statbuf, st64); + return ret; + } + + return (* smbw_libc.fstat64)(fd, st64); +} + +int __lxstat64(int ver, const char *name, struct stat64 *st64) +{ + check_init("__lxstat64"); + + if (smbw_path((char *) name)) { + struct SMBW_stat statbuf; + int ret = smbw_stat(name, &statbuf); + stat64_convert(&statbuf, st64); + return ret; + } + + return (* smbw_libc.__lxstat64)(ver, (char *) name, st64); +} + +int lstat64(const char *name, struct stat64 *st64) +{ + check_init("lstat64"); + + if (smbw_path((char *) name)) { + struct SMBW_stat statbuf; + int ret = smbw_stat((char *) name, &statbuf); + stat64_convert(&statbuf, st64); + return ret; + } + + return (* smbw_libc.lstat64)((char *) name, st64); +} + +int _llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t *result, unsigned int whence) +{ + check_init("_llseek"); + + if (smbw_fd(fd)) { + *result = lseek(fd, offset_low, whence); + return (*result < 0 ? -1 : 0); + } + + return (* smbw_libc._llseek)(fd, offset_high, offset_low, result, whence); +} + +struct dirent64 *readdir64(DIR *dir) +{ + check_init("readdir64"); + + if (smbw_dirp(dir)) { + static struct dirent64 external; + struct SMBW_dirent * internal = (void *)smbw_readdir(dir); + if (internal != NULL) { + dirent64_convert(internal, &external); + return &external; + } + return NULL; + } + + return (* smbw_libc.readdir64)(dir); +} + +int readdir_r(DIR *dir, struct dirent *external, struct dirent **result) +{ + check_init("readdir_r"); + + if (smbw_dirp(dir)) { + struct SMBW_dirent internal; + int ret = smbw_readdir_r(dir, &internal, NULL); + if (ret == 0) { + dirent_convert(&internal, external); + *result = external; + } + return ret; + } + + return (* smbw_libc.readdir_r)(dir, external, result); +} + +int readdir64_r(DIR *dir, struct dirent64 *external, struct dirent64 **result) +{ + check_init("readdir64_r"); + + if (smbw_dirp(dir)) { + struct SMBW_dirent internal; + int ret = smbw_readdir_r(dir, &internal, NULL); + if (ret == 0) { + dirent64_convert(&internal, external); + *result = external; + } + return ret; + } + + return (* smbw_libc.readdir64_r)(dir, external, result); +} + +int fork(void) +{ + check_init("fork"); + return smbw_fork(); +} + +int setxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags) +{ + if (smbw_path(fname)) { + return smbw_setxattr(fname, name, value, size, flags); + } + + return (* smbw_libc.setxattr)(fname, name, value, size, flags); +} + +int lsetxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags) +{ + if (smbw_path(fname)) { + return smbw_lsetxattr(fname, name, value, size, flags); + } + + return (* smbw_libc.lsetxattr)(fname, name, value, size, flags); +} + +int fsetxattr(int fd, + const char *name, + const void *value, + size_t size, + int flags) +{ + if (smbw_fd(fd)) { + return smbw_fsetxattr(fd, name, value, size, flags); + } + + return (* smbw_libc.fsetxattr)(fd, name, value, size, flags); +} + +int getxattr(const char *fname, + const char *name, + const void *value, + size_t size) +{ + if (smbw_path(fname)) { + return smbw_getxattr(fname, name, value, size); + } + + return (* smbw_libc.getxattr)(fname, name, value, size); +} + +int lgetxattr(const char *fname, + const char *name, + const void *value, + size_t size) +{ + if (smbw_path(fname)) { + return smbw_lgetxattr(fname, name, value, size); + } + + return (* smbw_libc.lgetxattr)(fname, name, value, size); +} + +int fgetxattr(int fd, + const char *name, + const void *value, + size_t size) +{ + if (smbw_fd(fd)) { + return smbw_fgetxattr(fd, name, value, size); + } + + return (* smbw_libc.fgetxattr)(fd, name, value, size); +} + +int removexattr(const char *fname, + const char *name) +{ + if (smbw_path(fname)) { + return smbw_removexattr(fname, name); + } + + return (* smbw_libc.removexattr)(fname, name); +} + +int lremovexattr(const char *fname, + const char *name) +{ + if (smbw_path(fname)) { + return smbw_lremovexattr(fname, name); + } + + return (* smbw_libc.lremovexattr)(fname, name); +} + +int fremovexattr(int fd, + const char *name) +{ + if (smbw_fd(fd)) { + return smbw_fremovexattr(fd, name); + } + + return (* smbw_libc.fremovexattr)(fd, name); +} + +int listxattr(const char *fname, + char *list, + size_t size) +{ + if (smbw_path(fname)) { + return smbw_listxattr(fname, list, size); + } + + return (* smbw_libc.listxattr)(fname, list, size); +} + +int llistxattr(const char *fname, + char *list, + size_t size) +{ + if (smbw_path(fname)) { + return smbw_llistxattr(fname, list, size); + } + + return (* smbw_libc.llistxattr)(fname, list, size); +} + +int flistxattr(int fd, + char *list, + size_t size) +{ + if (smbw_fd(fd)) { + return smbw_flistxattr(fd, list, size); + } + + return (* smbw_libc.flistxattr)(fd, list, size); +} + + +/* + * We're ending up with a different implementation of malloc() with smbwrapper + * than without it. The one with it does not support returning a non-NULL + * pointer from a call to malloc(0), and many apps depend on getting a valid + * pointer when requesting zero length (e.g. df, emacs). + * + * Unfortunately, initializing the smbw_libc[] array via the dynamic link + * library (libdl) requires malloc so we can't just do the same type of + * mapping to the C library as we do with everything else. We need to + * implement a different way of allocating memory that ensures that the C + * library version of malloc() gets used. This is the only place where we + * kludge the code to use an undocumented interface to the C library. + * + * If anyone can come up with a way to dynamically link to the C library + * rather than using this undocumented interface, I'd sure love to hear about + * it. Better yet, if you can figure out where the alternate malloc() + * functions are coming from and arrange for them not to be called, that would + * be even better. We should try to avoid wrapping functions that don't + * really require it. + */ + +void *malloc(size_t size) +{ + void *__libc_malloc(size_t size); + return __libc_malloc(size); +} + +void *calloc(size_t nmemb, size_t size) +{ + void *__libc_calloc(size_t nmemb, size_t size); + return __libc_calloc(nmemb, size); +} + +void *realloc(void *ptr, size_t size) +{ + void *__libc_realloc(void *ptr, size_t size); + return __libc_realloc(ptr, size); +} + +void free(void *ptr) +{ + static int in_progress = 0; + void __libc_free(void *ptr); + + if (in_progress) return; + in_progress = 1; + __libc_free(ptr); + in_progress = 0; +} + + +#if 0 /* SELECT */ + +static struct sigaction user_action[_NSIG]; + +static void +smbw_sigaction_handler(int signum, + siginfo_t *info, + void *context) +{ + /* Our entire purpose for trapping signals is to call this! */ + sys_select_signal(); + + /* Call the user's handler */ + if (user_action[signum].sa_handler != SIG_IGN && + user_action[signum].sa_handler != SIG_DFL && + user_action[signum].sa_handler != SIG_ERR) { + (* user_action[signum].sa_sigaction)(signum, info, context); + } +} + + +/* + * Every Samba signal handler must call sys_select_signal() to avoid a race + * condition, so we'll take whatever signal handler is currently assigned, + * call call sys_select_signal() in addition to their call. + */ +static int +do_select(int n, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout, + int (* select_fn)(int n, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout)) +{ + int i; + int ret; + int saved_errno; + sigset_t sigset; + struct sigaction new_action; + + saved_errno = errno; + for (i=1; i<_NSIG; i++) { + sigemptyset(&sigset); + new_action.sa_mask = sigset; + new_action.sa_flags = SA_SIGINFO; + new_action.sa_sigaction = smbw_sigaction_handler; + + if (sigaction(i, &new_action, &user_action[i]) < 0) { + if (errno != EINVAL) { + return -1; + } + } + } + errno = saved_errno; + + ret = (* select_fn)(n, readfds, writefds, exceptfds, timeout); + saved_errno = errno; + + for (i=0; i<_NSIG; i++) { + (void) sigaction(i, &user_action[i], NULL); + } + + errno = saved_errno; + return ret; +} + +int +select(int n, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout) +{ + check_init("select"); + + return do_select(n, readfds, writefds, exceptfds, + timeout, smbw_libc.select); +} + +int +_select(int n, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout) +{ + check_init("_select"); + + return do_select(n, readfds, writefds, exceptfds, + timeout, smbw_libc._select); +} + +int +__select(int n, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout) +{ + check_init("__select"); + + return do_select(n, readfds, writefds, exceptfds, + timeout, smbw_libc.__select); +} + +#endif diff --git a/examples/libsmbclient/smbwrapper/wrapper.h b/examples/libsmbclient/smbwrapper/wrapper.h new file mode 100644 index 0000000000..e83bb1ee5d --- /dev/null +++ b/examples/libsmbclient/smbwrapper/wrapper.h @@ -0,0 +1,212 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB wrapper functions + Copyright (C) Derrell Lipman 2003-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/>. +*/ + +#ifndef __WRAPPER_H__ +#define __WRAPPER_H__ + +#include <sys/stat.h> +#include <sys/select.h> +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> +#include <dirent.h> +#include <utime.h> +#include <signal.h> +#include <stdio.h> + +#ifndef __FD_SETSIZE +# define __FD_SETSIZE 256 +#endif + +extern int smbw_fd_map[__FD_SETSIZE]; +extern int smbw_ref_count[__FD_SETSIZE]; +extern char smbw_cwd[PATH_MAX]; +extern char smbw_prefix[]; + +typedef struct SMBW_stat { + unsigned long s_dev; /* device */ + unsigned long s_ino; /* inode */ + unsigned long s_mode; /* protection */ + unsigned long s_nlink; /* number of hard links */ + unsigned long s_uid; /* user ID of owner */ + unsigned long s_gid; /* group ID of owner */ + unsigned long s_rdev; /* device type (if inode device) */ + unsigned long long s_size; /* total size, in bytes */ + unsigned long s_blksize; /* blocksize for filesystem I/O */ + unsigned long s_blocks; /* number of blocks allocated */ + unsigned long s_atime; /* time of last access */ + unsigned long s_mtime; /* time of last modification */ + unsigned long s_ctime; /* time of last change */ +} SMBW_stat; + +typedef struct SMBW_dirent { + unsigned long d_ino; /* inode number */ + unsigned long long d_off; /* offset to the next dirent */ + unsigned long d_reclen; /* length of this record */ + unsigned long d_type; /* type of file */ + char d_name[256]; /* filename */ + char d_comment[256]; /* comment */ +} SMBW_dirent; + +struct kernel_sigaction { + __sighandler_t k_sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; +}; + +typedef struct SMBW_libc +{ + /* write() is first, to allow debugging */ + ssize_t (* write)(int fd, void *buf, size_t count); + int (* open)(char *name, int flags, mode_t mode); + int (* _open)(char *name, int flags, mode_t mode) ; + int (* __open)(char *name, int flags, mode_t mode) ; + int (* open64)(char *name, int flags, mode_t mode); + int (* _open64)(char *name, int flags, mode_t mode) ; + int (* __open64)(char *name, int flags, mode_t mode) ; + ssize_t (* pread)(int fd, void *buf, size_t size, off_t ofs); + ssize_t (* pread64)(int fd, void *buf, size_t size, off64_t ofs); + ssize_t (* pwrite)(int fd, void *buf, size_t size, off_t ofs); + ssize_t (* pwrite64)(int fd, void *buf, size_t size, off64_t ofs); + int (* close)(int fd); + int (* __close)(int fd); + int (* _close)(int fd); + int (* fcntl)(int fd, int cmd, long arg); + int (* __fcntl)(int fd, int cmd, long arg); + int (* _fcntl)(int fd, int cmd, long arg); + int (* getdents)(int fd, struct dirent *dirp, unsigned int count); + int (* __getdents)(int fd, struct dirent *dirp, unsigned int count); + int (* _getdents)(int fd, struct dirent *dirp, unsigned int count); + int (* getdents64)(int fd, struct dirent64 *dirp, unsigned int count); + off_t (* lseek)(int fd, off_t offset, int whence); + off_t (* __lseek)(int fd, off_t offset, int whence); + off_t (* _lseek)(int fd, off_t offset, int whence); + off64_t (* lseek64)(int fd, off64_t offset, int whence); + off64_t (* __lseek64)(int fd, off64_t offset, int whence); + off64_t (* _lseek64)(int fd, off64_t offset, int whence); + ssize_t (* read)(int fd, void *buf, size_t count); + ssize_t (* __read)(int fd, void *buf, size_t count); + ssize_t (* _read)(int fd, void *buf, size_t count); + ssize_t (* __write)(int fd, void *buf, size_t count); + ssize_t (* _write)(int fd, void *buf, size_t count); + int (* access)(char *name, int mode); + int (* chmod)(char *name, mode_t mode); + int (* fchmod)(int fd, mode_t mode); + int (* chown)(char *name, uid_t owner, gid_t group); + int (* fchown)(int fd, uid_t owner, gid_t group); + int (* __xstat)(int vers, char *name, struct stat *st); + char * ( *getcwd)(char *buf, size_t size); + int (* mkdir)(char *name, mode_t mode); + int (* __fxstat)(int vers, int fd, struct stat *st); + int (* __lxstat)(int vers, char *name, struct stat *st); + int (* stat)(char *name, struct stat *st); + int (* lstat)(char *name, struct stat *st); + int (* fstat)(int fd, struct stat *st); + int (* unlink)(char *name); + int (* utime)(char *name, struct utimbuf *tvp); + int (* utimes)(char *name, struct timeval *tvp); + int (* readlink)(char *path, char *buf, size_t bufsize); + int (* rename)(char *oldname, char *newname); + int (* rmdir)(char *name); + int (* symlink)(char *topath, char *frompath); + int (* dup)(int fd); + int (* dup2)(int oldfd, int newfd); + DIR * (* opendir)(char *name); + struct dirent * (* readdir)(DIR *dir); + int (* closedir)(DIR *dir); + off_t (* telldir)(DIR *dir); + void (* seekdir)(DIR *dir, off_t offset); + int (* creat)(char *path, mode_t mode); + int (* creat64)(char *path, mode_t mode); + int (* __xstat64)(int ver, char *name, struct stat64 *st64); + int (* stat64)(char *name, struct stat64 *st64); + int (* __fxstat64)(int ver, int fd, struct stat64 *st64); + int (* fstat64)(int fd, struct stat64 *st64); + int (* __lxstat64)(int ver, char *name, struct stat64 *st64); + int (* lstat64)(char *name, struct stat64 *st64); + int (* _llseek)(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t *result, unsigned int whence); + struct dirent64 * (* readdir64)(DIR *dir); + int (* readdir_r)(DIR *dir, struct dirent *entry, struct dirent **result); + int (* readdir64_r)(DIR *dir, struct dirent64 *entry, struct dirent64 **result); + int (* setxattr)(const char *fname, + const char *name, + const void *value, + size_t size, + int flags); + int (* lsetxattr)(const char *fname, + const char *name, + const void *value, + size_t size, + int flags); + int (* fsetxattr)(int smbw_fd, + const char *name, + const void *value, + size_t size, + int flags); + int (* getxattr)(const char *fname, + const char *name, + const void *value, + size_t size); + int (* lgetxattr)(const char *fname, + const char *name, + const void *value, + size_t size); + int (* fgetxattr)(int smbw_fd, + const char *name, + const void *value, + size_t size); + int (* removexattr)(const char *fname, + const char *name); + int (* lremovexattr)(const char *fname, + const char *name); + int (* fremovexattr)(int smbw_fd, + const char *name); + int (* listxattr)(const char *fname, + char *list, + size_t size); + int (* llistxattr)(const char *fname, + char *list, + size_t size); + int (* flistxattr)(int smbw_fd, + char *list, + size_t size); + int (* chdir)(const char *path); + int (* fchdir)(int fd); + pid_t (* fork)(void); + int (* select)(int n, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout); + int (* _select)(int n, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout); + int (* __select)(int n, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout); +} SMBW_libc_pointers; + +extern SMBW_libc_pointers smbw_libc; + +#endif /* __WRAPPER_H__ */ diff --git a/examples/libsmbclient/testacl.c b/examples/libsmbclient/testacl.c new file mode 100644 index 0000000000..a57dd4a499 --- /dev/null +++ b/examples/libsmbclient/testacl.c @@ -0,0 +1,284 @@ +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <popt.h> +#include "libsmbclient.h" +#include "get_auth_data_fn.h" + +enum acl_mode +{ + SMB_ACL_LIST, + SMB_ACL_GET, + SMB_ACL_SET, + SMB_ACL_DELETE, + SMB_ACL_MODIFY, + SMB_ACL_ADD, + SMB_ACL_CHOWN, + SMB_ACL_CHGRP +}; + + +int main(int argc, const char *argv[]) +{ + int opt; + int flags; + int debug = 0; + int numeric = 0; + int stat_and_retry = 0; + int full_time_names = 0; + enum acl_mode mode = SMB_ACL_LIST; + static char *the_acl = NULL; + int ret; + char *p; + char *debugstr; + char path[1024]; + char value[1024]; + poptContext pc; + struct stat st; + struct poptOption long_options[] = + { + POPT_AUTOHELP + { + "numeric", 'n', POPT_ARG_NONE, &numeric, + 1, "Don't resolve sids or masks to names" + }, + { + "debug", 'd', POPT_ARG_INT, &debug, + 0, "Set debug level (0-100)" + }, + { + "full_time_names", 'f', POPT_ARG_NONE, &full_time_names, + 1, + "Use new style xattr names, which include CREATE_TIME" + }, + { + "delete", 'D', POPT_ARG_STRING, NULL, + 'D', "Delete an acl", "ACL" + }, + { + "modify", 'M', POPT_ARG_STRING, NULL, + 'M', "Modify an acl", "ACL" + }, + { + "add", 'a', POPT_ARG_STRING, NULL, + 'a', "Add an acl", "ACL" + }, + { + "set", 'S', POPT_ARG_STRING, NULL, + 'S', "Set acls", "ACLS" + }, + { + "chown", 'C', POPT_ARG_STRING, NULL, + 'C', "Change ownership of a file", "USERNAME" + }, + { + "chgrp", 'G', POPT_ARG_STRING, NULL, + 'G', "Change group ownership of a file", "GROUPNAME" + }, + { + "get", 'g', POPT_ARG_STRING, NULL, + 'g', "Get a specific acl attribute", "ACL" + }, + { + "stat_and_retry", 'R', POPT_ARG_NONE, &stat_and_retry, + 1, "After 'get' do 'stat' and another 'get'" + }, + { + NULL + } + }; + + setbuf(stdout, NULL); + + pc = poptGetContext("smbcacls", argc, argv, long_options, 0); + + poptSetOtherOptionHelp(pc, "smb://server1/share1/filename"); + + while ((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + case 'S': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_SET; + break; + + case 'D': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_DELETE; + break; + + case 'M': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_MODIFY; + break; + + case 'a': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_ADD; + break; + + case 'g': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_GET; + break; + + case 'C': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_CHOWN; + break; + + case 'G': + the_acl = strdup(poptGetOptArg(pc)); + mode = SMB_ACL_CHGRP; + break; + } + } + + /* Make connection to server */ + if(!poptPeekArg(pc)) { + poptPrintUsage(pc, stderr, 0); + return 1; + } + + strcpy(path, poptGetArg(pc)); + + if (smbc_init(get_auth_data_fn, debug) != 0) + { + printf("Could not initialize smbc_ library\n"); + return 1; + } + + if (full_time_names) { + SMBCCTX *context = smbc_set_context(NULL); + smbc_setOptionFullTimeNames(context, 1); + } + + /* Perform requested action */ + + switch(mode) + { + case SMB_ACL_LIST: + ret = smbc_listxattr(path, value, sizeof(value)-2); + if (ret < 0) + { + printf("Could not get attribute list for [%s] %d: %s\n", + path, errno, strerror(errno)); + return 1; + } + + /* + * The list of attributes has a series of null-terminated strings. + * The list of strings terminates with an extra null byte, thus two in + * a row. Ensure that our buffer, which is conceivably shorter than + * the list of attributes, actually ends with two null bytes in a row. + */ + value[sizeof(value) - 2] = '\0'; + value[sizeof(value) - 1] = '\0'; + printf("Supported attributes:\n"); + for (p = value; *p; p += strlen(p) + 1) + { + printf("\t%s\n", p); + } + break; + + case SMB_ACL_GET: + do + { + if (the_acl == NULL) + { + if (numeric) + { + the_acl = "system.*"; + } + else + { + the_acl = "system.*+"; + } + } + ret = smbc_getxattr(path, the_acl, value, sizeof(value)); + if (ret < 0) + { + printf("Could not get attributes for [%s] %d: %s\n", + path, errno, strerror(errno)); + return 1; + } + + printf("Attributes for [%s] are:\n%s\n", path, value); + + if (stat_and_retry) + { + if (smbc_stat(path, &st) < 0) + { + perror("smbc_stat"); + return 1; + } + } + + --stat_and_retry; + } while (stat_and_retry >= 0); + break; + + case SMB_ACL_ADD: + flags = SMBC_XATTR_FLAG_CREATE; + debugstr = "add attributes"; + goto do_set; + + case SMB_ACL_MODIFY: + flags = SMBC_XATTR_FLAG_REPLACE; + debugstr = "modify attributes"; + goto do_set; + + case SMB_ACL_CHOWN: + snprintf(value, sizeof(value), + "system.nt_sec_desc.owner%s:%s", + numeric ? "" : "+", the_acl); + the_acl = value; + debugstr = "chown owner"; + goto do_set; + + case SMB_ACL_CHGRP: + snprintf(value, sizeof(value), + "system.nt_sec_desc.group%s:%s", + numeric ? "" : "+", the_acl); + the_acl = value; + debugstr = "change group"; + goto do_set; + + case SMB_ACL_SET: + flags = 0; + debugstr = "set attributes"; + + do_set: + if ((p = strchr(the_acl, ':')) == NULL) + { + printf("Missing value. ACL must be name:value pair\n"); + return 1; + } + + *p++ = '\0'; + + ret = smbc_setxattr(path, the_acl, p, strlen(p), flags); + if (ret < 0) + { + printf("Could not %s for [%s] %d: %s\n", + debugstr, path, errno, strerror(errno)); + return 1; + } + break; + + case SMB_ACL_DELETE: + ret = smbc_removexattr(path, the_acl); + if (ret < 0) + { + printf("Could not remove attribute %s for [%s] %d:%s\n", + the_acl, path, errno, strerror(errno)); + return 1; + } + break; + + default: + printf("operation not yet implemented\n"); + break; + } + + return 0; +} diff --git a/examples/libsmbclient/testacl2.c b/examples/libsmbclient/testacl2.c new file mode 100644 index 0000000000..d2a97cf2d2 --- /dev/null +++ b/examples/libsmbclient/testacl2.c @@ -0,0 +1,78 @@ +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <popt.h> +#include "libsmbclient.h" +#include "get_auth_data_fn.h" + +enum acl_mode +{ + SMB_ACL_GET, + SMB_ACL_SET, + SMB_ACL_DELETE, + SMB_ACL_MODIFY, + SMB_ACL_ADD, + SMB_ACL_CHOWN, + SMB_ACL_CHGRP +}; + + +int main(int argc, const char *argv[]) +{ + int i; + int opt; + int flags; + int debug = 0; + int numeric = 0; + int full_time_names = 0; + enum acl_mode mode = SMB_ACL_GET; + static char *the_acl = NULL; + int ret; + char *p; + char *debugstr; + char value[1024]; + + if (smbc_init(get_auth_data_fn, debug) != 0) + { + printf("Could not initialize smbc_ library\n"); + return 1; + } + + SMBCCTX *context = smbc_set_context(NULL); + smbc_setOptionFullTimeNames(context, 1); + + the_acl = strdup("system.nt_sec_desc.*"); + ret = smbc_getxattr(argv[1], the_acl, value, sizeof(value)); + if (ret < 0) + { + printf("Could not get attributes for [%s] %d: %s\n", + argv[1], errno, strerror(errno)); + return 1; + } + + printf("Attributes for [%s] are:\n%s\n", argv[1], value); + + flags = 0; + debugstr = "set attributes (1st time)"; + + ret = smbc_setxattr(argv[1], the_acl, value, strlen(value), flags); + if (ret < 0) + { + printf("Could not %s for [%s] %d: %s\n", + debugstr, argv[1], errno, strerror(errno)); + return 1; + } + + flags = 0; + debugstr = "set attributes (2nd time)"; + + ret = smbc_setxattr(argv[1], the_acl, value, strlen(value), flags); + if (ret < 0) + { + printf("Could not %s for [%s] %d: %s\n", + debugstr, argv[1], errno, strerror(errno)); + return 1; + } + + return 0; +} diff --git a/examples/libsmbclient/testacl3.c b/examples/libsmbclient/testacl3.c new file mode 100644 index 0000000000..4ef6e80a7b --- /dev/null +++ b/examples/libsmbclient/testacl3.c @@ -0,0 +1,62 @@ +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <time.h> +#include <errno.h> +#include <libsmbclient.h> +#include "get_auth_data_fn.h" + + +int main(int argc, char * argv[]) +{ + int i; + int fd; + int ret; + int debug = 0; + int mode = 0666; + int savedErrno; + char value[2048]; + char path[2048]; + char * the_acl; + char * p; + time_t t0; + time_t t1; + struct stat st; + SMBCCTX * context; + + smbc_init(get_auth_data_fn, debug); + + context = smbc_set_context(NULL); + smbc_setOptionFullTimeNames(context, 1); + + for (;;) + { + fprintf(stdout, "Path: "); + *path = '\0'; + fgets(path, sizeof(path) - 1, stdin); + if (strlen(path) == 0) + { + return 0; + } + + p = path + strlen(path) - 1; + if (*p == '\n') + { + *p = '\0'; + } + + the_acl = strdup("system.nt_sec_desc.*+"); + ret = smbc_getxattr(path, the_acl, value, sizeof(value)); + if (ret < 0) + { + printf("Could not get attributes for [%s] %d: %s\n", + path, errno, strerror(errno)); + return 1; + } + + printf("Attributes for [%s] are:\n%s\n", path, value); + } + + return 0; +} diff --git a/examples/libsmbclient/testbrowse.c b/examples/libsmbclient/testbrowse.c new file mode 100644 index 0000000000..a6e6395078 --- /dev/null +++ b/examples/libsmbclient/testbrowse.c @@ -0,0 +1,310 @@ +#include <sys/types.h> +#include <unistd.h> +#include <dirent.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <popt.h> +#include <stdlib.h> +#include <libsmbclient.h> +#include "get_auth_data_fn.h" + +static void +no_auth_data_fn(const char * pServer, + const char * pShare, + char * pWorkgroup, + int maxLenWorkgroup, + char * pUsername, + int maxLenUsername, + char * pPassword, + int maxLenPassword); + +static void browse(char * path, + int scan, + int indent); + + +static void +get_auth_data_with_context_fn(SMBCCTX * context, + const char * pServer, + const char * pShare, + char * pWorkgroup, + int maxLenWorkgroup, + char * pUsername, + int maxLenUsername, + char * pPassword, + int maxLenPassword); + +int +main(int argc, char * argv[]) +{ + int debug = 0; + int debug_stderr = 0; + int no_auth = 0; + int context_auth = 0; + int scan = 0; + int iterations = -1; + int again; + int opt; + char * p; + char * q; + char buf[1024]; + poptContext pc; + SMBCCTX * context; + struct poptOption long_options[] = + { + POPT_AUTOHELP + { + "debug", 'd', POPT_ARG_INT, &debug, + 0, "Set debug level", "integer" + }, + { + "stderr", 'e', POPT_ARG_NONE, &debug_stderr, + 0, "Debug log to stderr instead of stdout", "integer" + }, + { + "scan", 's', POPT_ARG_NONE, &scan, + 0, "Scan for servers and shares", "integer" + }, + { + "iterations", 'i', POPT_ARG_INT, &iterations, + 0, "Iterations", "integer" + }, + { + "noauth", 'A', POPT_ARG_NONE, &no_auth, + 0, "Do not request authentication data", "integer" + }, + { + "contextauth", 'C', POPT_ARG_NONE, &context_auth, + 0, "Use new authentication function with context", "integer" + }, + { + NULL + } + }; + + setbuf(stdout, NULL); + + pc = poptGetContext("opendir", argc, (const char **)argv, long_options, 0); + + poptSetOtherOptionHelp(pc, ""); + + while ((opt = poptGetNextOpt(pc)) != -1) { + printf("Got option %d = %c\n", opt, opt); + switch (opt) { + } + } + + /* Allocate a new context */ + context = smbc_new_context(); + if (!context) { + printf("Could not allocate new smbc context\n"); + return 1; + } + + /* If we're scanning, do no requests for authentication data */ + if (scan) { + no_auth = 1; + } + + /* Set mandatory options (is that a contradiction in terms?) */ + smbc_setDebug(context, debug); + if (context_auth) { + smbc_setFunctionAuthDataWithContext(context, + get_auth_data_with_context_fn); + smbc_setOptionUserData(context, "hello world"); + } else { + smbc_setFunctionAuthData(context, get_auth_data_fn); + } + + smbc_setOptionUseKerberos(context, 1); + smbc_setOptionFallbackAfterKerberos(context, 1); + + /* If we've been asked to log to stderr instead of stdout, ... */ + if (debug_stderr) { + /* ... then set the option to do so */ + smbc_setOptionDebugToStderr(context, 1); + } + + /* Initialize the context using the previously specified options */ + if (!smbc_init_context(context)) { + smbc_free_context(context, 0); + printf("Could not initialize smbc context\n"); + return 1; + } + + /* Tell the compatibility layer to use this context */ + smbc_set_context(context); + + if (scan) + { + for (; + iterations == -1 || iterations > 0; + iterations = (iterations == -1 ? iterations : --iterations)) + { + snprintf(buf, sizeof(buf), "smb://"); + browse(buf, scan, 0); + } + } + else + { + for (; + iterations == -1 || iterations > 0; + iterations = (iterations == -1 ? iterations : --iterations)) + { + fputs("url: ", stdout); + p = fgets(buf, sizeof(buf), stdin); + if (! p) + { + break; + } + + if ((p = strchr(buf, '\n')) != NULL) + { + *p = '\0'; + } + + browse(buf, scan, 0); + } + } + + exit(0); +} + + +static void +no_auth_data_fn(const char * pServer, + const char * pShare, + char * pWorkgroup, + int maxLenWorkgroup, + char * pUsername, + int maxLenUsername, + char * pPassword, + int maxLenPassword) +{ + return; +} + + +static void +get_auth_data_with_context_fn(SMBCCTX * context, + const char * pServer, + const char * pShare, + char * pWorkgroup, + int maxLenWorkgroup, + char * pUsername, + int maxLenUsername, + char * pPassword, + int maxLenPassword) +{ + printf("Authenticating with context 0x%lx", context); + if (context != NULL) { + char *user_data = smbc_getOptionUserData(context); + printf(" with user data %s", user_data); + } + printf("\n"); + + get_auth_data_fn(pServer, pShare, pWorkgroup, maxLenWorkgroup, + pUsername, maxLenUsername, pPassword, maxLenPassword); +} + +static void browse(char * path, int scan, int indent) +{ + char * p; + char buf[1024]; + int dir; + struct stat stat; + struct smbc_dirent * dirent; + + if (! scan) + { + printf("Opening (%s)...\n", path); + } + + if ((dir = smbc_opendir(path)) < 0) + { + printf("Could not open directory [%s] (%d:%s)\n", + path, errno, strerror(errno)); + return; + } + + while ((dirent = smbc_readdir(dir)) != NULL) + { + printf("%*.*s%-30s", indent, indent, "", dirent->name); + + switch(dirent->smbc_type) + { + case SMBC_WORKGROUP: + printf("WORKGROUP"); + break; + + case SMBC_SERVER: + printf("SERVER"); + break; + + case SMBC_FILE_SHARE: + printf("FILE_SHARE"); + break; + + case SMBC_PRINTER_SHARE: + printf("PRINTER_SHARE"); + break; + + case SMBC_COMMS_SHARE: + printf("COMMS_SHARE"); + break; + + case SMBC_IPC_SHARE: + printf("IPC_SHARE"); + break; + + case SMBC_DIR: + printf("DIR"); + break; + + case SMBC_FILE: + printf("FILE"); + + p = path + strlen(path); + strcat(p, "/"); + strcat(p+1, dirent->name); + if (smbc_stat(path, &stat) < 0) + { + printf(" unknown size (reason %d: %s)", + errno, strerror(errno)); + } + else + { + printf(" size %lu", (unsigned long) stat.st_size); + } + *p = '\0'; + + break; + + case SMBC_LINK: + printf("LINK"); + break; + } + + printf("\n"); + + if (scan && + (dirent->smbc_type == SMBC_WORKGROUP || + dirent->smbc_type == SMBC_SERVER)) + { + /* + * don't append server name to workgroup; what we want is: + * + * smb://workgroup_name + * or + * smb://server_name + * + */ + snprintf(buf, sizeof(buf), "smb://%s", dirent->name); + browse(buf, scan, indent + 2); + } + } + + smbc_closedir(dir); +} + diff --git a/examples/libsmbclient/testbrowse2.c b/examples/libsmbclient/testbrowse2.c new file mode 100644 index 0000000000..0ac1d72bb4 --- /dev/null +++ b/examples/libsmbclient/testbrowse2.c @@ -0,0 +1,215 @@ +/* + * Alternate testbrowse utility provided by Mikhail Kshevetskiy. + * This version tests use of multiple contexts. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <malloc.h> +#include <string.h> +#include <libsmbclient.h> + +int debuglevel = 0; +char *workgroup = "NT"; +char *username = "guest"; +char *password = ""; + +typedef struct smbitem smbitem; +typedef int(*qsort_cmp)(const void *, const void *); + +struct smbitem{ + smbitem *next; + int type; + char name[1]; +}; + +int smbitem_cmp(smbitem *elem1, smbitem *elem2){ + return strcmp(elem1->name, elem2->name); +} + +int smbitem_list_count(smbitem *list){ + int count = 0; + + while(list != NULL){ + list = list->next; + count++; + } + return count; +} + +void smbitem_list_delete(smbitem *list){ + smbitem *elem; + + while(list != NULL){ + elem = list; + list = list->next; + free(elem); + } +} + +smbitem* smbitem_list_sort(smbitem *list){ + smbitem *item, **array; + int count, i; + + if ((count = smbitem_list_count(list)) == 0) return NULL; + if ((array = malloc(count * sizeof(smbitem*))) == NULL){ + smbitem_list_delete(list); + return NULL; + } + + for(i = 0; i < count; i++){ + array[i] = list; + list = list->next; + } + qsort(array, count, sizeof(smbitem*), (qsort_cmp)smbitem_cmp); + + for(i = 0; i < count - 1; i++) array[i]->next = array[i + 1]; + array[count - 1]->next = NULL; + + list = array[0]; + free(array); + return list; +} + +void smbc_auth_fn( + const char *server, + const char *share, + char *wrkgrp, int wrkgrplen, + char *user, int userlen, + char *passwd, int passwdlen){ + + (void) server; + (void) share; + (void) wrkgrp; + (void) wrkgrplen; + + strncpy(wrkgrp, workgroup, wrkgrplen - 1); wrkgrp[wrkgrplen - 1] = 0; + strncpy(user, username, userlen - 1); user[userlen - 1] = 0; + strncpy(passwd, password, passwdlen - 1); passwd[passwdlen - 1] = 0; +} + +SMBCCTX* create_smbctx(){ + SMBCCTX *ctx; + + if ((ctx = smbc_new_context()) == NULL) return NULL; + + smbc_setDebug(ctx, debuglevel); + smbc_setFunctionAuthData(ctx, smbc_auth_fn); + + if (smbc_init_context(ctx) == NULL){ + smbc_free_context(ctx, 1); + return NULL; + } + + return ctx; +} + +void delete_smbctx(SMBCCTX* ctx){ + smbc_getFunctionPurgeCachedServers(ctx)(ctx); + smbc_free_context(ctx, 1); +} + +smbitem* get_smbitem_list(SMBCCTX *ctx, char *smb_path){ + SMBCFILE *fd; + struct smbc_dirent *dirent; + smbitem *list = NULL, *item; + + if ((fd = smbc_getFunctionOpendir(ctx)(ctx, smb_path)) == NULL) + return NULL; + while((dirent = smbc_getFunctionReaddir(ctx)(ctx, fd)) != NULL){ + if (strcmp(dirent->name, "") == 0) continue; + if (strcmp(dirent->name, ".") == 0) continue; + if (strcmp(dirent->name, "..") == 0) continue; + + if ((item = malloc(sizeof(smbitem) + strlen(dirent->name))) == NULL) + continue; + + item->next = list; + item->type = dirent->smbc_type; + strcpy(item->name, dirent->name); + list = item; + } + smbc_getFunctionClose(ctx)(ctx, fd); + return /* smbitem_list_sort */ (list); + +} + +void print_smb_path(char *group, char *path){ + if ((strlen(group) == 0) && (strlen(path) == 0)) printf("/\n"); + else if (strlen(path) == 0) printf("/%s\n", group); + else{ + if (strlen(group) == 0) group = "(unknown_group)"; + printf("/%s/%s\n", group, path); + } +} + +void recurse(SMBCCTX *ctx, char *smb_group, char *smb_path, int maxlen){ + int len; + smbitem *list, *item; + SMBCCTX *ctx1; + + len = strlen(smb_path); + + list = get_smbitem_list(ctx, smb_path); + while(list != NULL){ + switch(list->type){ + case SMBC_WORKGROUP: + case SMBC_SERVER: + if (list->type == SMBC_WORKGROUP){ + print_smb_path(list->name, ""); + smb_group = list->name; + } + else print_smb_path(smb_group, list->name); + + if (maxlen < 7 + strlen(list->name)) break; + strcpy(smb_path + 6, list->name); + if ((ctx1 = create_smbctx()) != NULL){ + recurse(ctx1, smb_group, smb_path, maxlen); + delete_smbctx(ctx1); + }else{ + recurse(ctx, smb_group, smb_path, maxlen); + smbc_getFunctionPurgeCachedServers(ctx)(ctx); + } + break; + case SMBC_FILE_SHARE: + case SMBC_DIR: + case SMBC_FILE: + if (maxlen < len + strlen(list->name) + 2) break; + + smb_path[len] = '/'; + strcpy(smb_path + len + 1, list->name); + print_smb_path(smb_group, smb_path + 6); + if (list->type != SMBC_FILE){ + recurse(ctx, smb_group, smb_path, maxlen); + if (list->type == SMBC_FILE_SHARE) + smbc_getFunctionPurgeCachedServers(ctx)(ctx); + } + break; + } + item = list; + list = list->next; + free(item); + } + smb_path[len] = '\0'; +} + +int main(int argc, char *argv[]){ + int i; + SMBCCTX *ctx; + char smb_path[32768] = "smb://"; + + if ((ctx = create_smbctx()) == NULL){ + perror("Cant create samba context."); + return 1; + } + + if (argc == 1) recurse(ctx, "", smb_path, sizeof(smb_path)); + else for(i = 1; i < argc; i++){ + strncpy(smb_path + 6, argv[i], sizeof(smb_path) - 7); + smb_path[sizeof(smb_path) - 1] = '\0'; + recurse(ctx, "", smb_path, sizeof(smb_path)); + } + + delete_smbctx(ctx); + return 0; +} diff --git a/examples/libsmbclient/testchmod.c b/examples/libsmbclient/testchmod.c new file mode 100644 index 0000000000..774daaed59 --- /dev/null +++ b/examples/libsmbclient/testchmod.c @@ -0,0 +1,64 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <time.h> +#include <libsmbclient.h> +#include "get_auth_data_fn.h" + + +int main(int argc, char * argv[]) +{ + int ret; + int debug = 0; + int mode = 0666; + char buffer[16384]; + char * pSmbPath = NULL; + struct stat st; + + if (argc == 1) + { + pSmbPath = "smb://RANDOM/Public/small"; + } + else if (argc == 2) + { + pSmbPath = argv[1]; + } + else if (argc == 3) + { + pSmbPath = argv[1]; + mode = (int) strtol(argv[2], NULL, 8); + } + else + { + printf("usage: " + "%s [ smb://path/to/file [ octal_mode ] ]\n", + argv[0]); + return 1; + } + + smbc_init(get_auth_data_fn, debug); + + if (smbc_stat(pSmbPath, &st) < 0) + { + perror("smbc_stat"); + return 1; + } + + printf("\nBefore chmod: mode = %04o\n", st.st_mode); + + if (smbc_chmod(pSmbPath, mode) < 0) + { + perror("smbc_chmod"); + return 1; + } + + if (smbc_stat(pSmbPath, &st) < 0) + { + perror("smbc_stat"); + return 1; + } + + printf("After chmod: mode = %04o\n", st.st_mode); + + return 0; +} diff --git a/examples/libsmbclient/testctx.c b/examples/libsmbclient/testctx.c new file mode 100644 index 0000000000..8820bc8342 --- /dev/null +++ b/examples/libsmbclient/testctx.c @@ -0,0 +1,17 @@ +#include <libsmbclient.h> + +void create_and_destroy_context (void) +{ + SMBCCTX *ctx; + ctx = smbc_new_context (); + smbc_init_context (ctx); + + smbc_free_context (ctx, 1); +} + +int main (int argc, char **argv) +{ + create_and_destroy_context (); + create_and_destroy_context (); + return 0; +} diff --git a/examples/libsmbclient/testread.c b/examples/libsmbclient/testread.c new file mode 100644 index 0000000000..3f94884895 --- /dev/null +++ b/examples/libsmbclient/testread.c @@ -0,0 +1,67 @@ +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <time.h> +#include <errno.h> +#include <libsmbclient.h> +#include "get_auth_data_fn.h" + + +int main(int argc, char * argv[]) +{ + int i; + int fd; + int ret; + int debug = 0; + int mode = 0666; + int savedErrno; + char buffer[2048]; + char path[2048]; + char * p; + time_t t0; + time_t t1; + struct stat st; + + smbc_init(get_auth_data_fn, debug); + + for (;;) + { + fprintf(stdout, "Path: "); + *path = '\0'; + fgets(path, sizeof(path) - 1, stdin); + if (strlen(path) == 0) + { + return 0; + } + + p = path + strlen(path) - 1; + if (*p == '\n') + { + *p = '\0'; + } + + if ((fd = smbc_open(path, O_RDONLY, 0)) < 0) + { + perror("smbc_open"); + continue; + } + + do + { + ret = smbc_read(fd, buffer, sizeof(buffer)); + savedErrno = errno; + if (ret > 0) fwrite(buffer, 1, ret, stdout); + } while (ret > 0); + + smbc_close(fd); + + if (ret < 0) + { + errno = savedErrno; + perror("read"); + } + } + + return 0; +} diff --git a/examples/libsmbclient/testsmbc.c b/examples/libsmbclient/testsmbc.c new file mode 100644 index 0000000000..1f06437293 --- /dev/null +++ b/examples/libsmbclient/testsmbc.c @@ -0,0 +1,301 @@ +/* + Unix SMB/CIFS implementation. + SMB client library test program + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000 + Copyright (C) John Terpsra 2000 + + 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/>. +*/ + +#include <stdio.h> +#include <errno.h> +#include <sys/time.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include "libsmbclient.h" +#include "get_auth_data_fn.h" + +int global_id = 0; + +void print_list_fn(struct print_job_info *pji) +{ + + fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n", + pji->id, pji->priority, pji->size, pji->user, pji->name); + + global_id = pji->id; + +} + +int main(int argc, char *argv[]) +{ + int err, fd, dh1, dh2, dh3, dsize, dirc; + const char *file = "smb://samba/public/testfile.txt"; + const char *file2 = "smb://samba/public/testfile2.txt"; + char buff[256]; + char dirbuf[512]; + char *dirp; + struct stat st1, st2; + + err = smbc_init(get_auth_data_fn, 10); /* Initialize things */ + + if (err < 0) { + + fprintf(stderr, "Initializing the smbclient library ...: %s\n", strerror(errno)); + + } + + if (argc > 1) { + + if ((dh1 = smbc_opendir(argv[1]))<1) { + + fprintf(stderr, "Could not open directory: %s: %s\n", + argv[1], strerror(errno)); + + exit(1); + + } + + fprintf(stdout, "Directory handles: %u, %u, %u\n", dh1, dh2, dh3); + + /* Now, list those directories, but in funny ways ... */ + + dirp = (char *)dirbuf; + + if ((dirc = smbc_getdents(dh1, (struct smbc_dirent *)dirp, + sizeof(dirbuf))) < 0) { + + fprintf(stderr, "Problems getting directory entries: %s\n", + strerror(errno)); + + exit(1); + + } + + /* Now, process the list of names ... */ + + fprintf(stdout, "Directory listing, size = %u\n", dirc); + + while (dirc > 0) { + + dsize = ((struct smbc_dirent *)dirp)->dirlen; + fprintf(stdout, "Dir Ent, Type: %u, Name: %s, Comment: %s\n", + ((struct smbc_dirent *)dirp)->smbc_type, + ((struct smbc_dirent *)dirp)->name, + ((struct smbc_dirent *)dirp)->comment); + + dirp += dsize; + dirc -= dsize; + + } + + dirp = (char *)dirbuf; + + exit(1); + + } + + /* For now, open a file on a server that is hard coded ... later will + * read from the command line ... + */ + + fd = smbc_open(file, O_RDWR | O_CREAT | O_TRUNC, 0666); + + if (fd < 0) { + + fprintf(stderr, "Creating file: %s: %s\n", file, strerror(errno)); + exit(0); + + } + + fprintf(stdout, "Opened or created file: %s\n", file); + + /* Now, write some date to the file ... */ + + bzero(buff, sizeof(buff)); + strcpy(buff, "Some test data for the moment ..."); + + err = smbc_write(fd, buff, sizeof(buff)); + + if (err < 0) { + + fprintf(stderr, "writing file: %s: %s\n", file, strerror(errno)); + exit(0); + + } + + fprintf(stdout, "Wrote %d bytes to file: %s\n", sizeof(buff), buff); + + /* Now, seek the file back to offset 0 */ + + err = smbc_lseek(fd, SEEK_SET, 0); + + if (err < 0) { + + fprintf(stderr, "Seeking file: %s: %s\n", file, strerror(errno)); + exit(0); + + } + + fprintf(stdout, "Completed lseek on file: %s\n", file); + + /* Now, read the file contents back ... */ + + err = smbc_read(fd, buff, sizeof(buff)); + + if (err < 0) { + + fprintf(stderr, "Reading file: %s: %s\n", file, strerror(errno)); + exit(0); + + } + + fprintf(stdout, "Read file: %s\n", buff); /* Should check the contents */ + + fprintf(stdout, "Now fstat'ing file: %s\n", file); + + err = smbc_fstat(fd, &st1); + + if (err < 0) { + + fprintf(stderr, "Fstat'ing file: %s: %s\n", file, strerror(errno)); + exit(0); + + } + + + /* Now, close the file ... */ + + err = smbc_close(fd); + + if (err < 0) { + + fprintf(stderr, "Closing file: %s: %s\n", file, strerror(errno)); + + } + + /* Now, rename the file ... */ + + err = smbc_rename(file, file2); + + if (err < 0) { + + fprintf(stderr, "Renaming file: %s to %s: %s\n", file, file2, strerror(errno)); + + } + + fprintf(stdout, "Renamed file %s to %s\n", file, file2); + + /* Now, create a file and delete it ... */ + + fprintf(stdout, "Now, creating file: %s so we can delete it.\n", file); + + fd = smbc_open(file, O_RDWR | O_CREAT, 0666); + + if (fd < 0) { + + fprintf(stderr, "Creating file: %s: %s\n", file, strerror(errno)); + exit(0); + + } + + fprintf(stdout, "Opened or created file: %s\n", file); + + err = smbc_close(fd); + + if (err < 0) { + + fprintf(stderr, "Closing file: %s: %s\n", file, strerror(errno)); + exit(0); + + } + + /* Now, delete the file ... */ + + fprintf(stdout, "File %s created, now deleting ...\n", file); + + err = smbc_unlink(file); + + if (err < 0) { + + fprintf(stderr, "Deleting file: %s: %s\n", file, strerror(errno)); + exit(0); + + } + + /* Now, stat the file, file 2 ... */ + + fprintf(stdout, "Now stat'ing file: %s\n", file); + + err = smbc_stat(file2, &st2); + + if (err < 0) { + + fprintf(stderr, "Stat'ing file: %s: %s\n", file, strerror(errno)); + exit(0); + + } + + fprintf(stdout, "Stat'ed file: %s. Size = %d, mode = %04X\n", file2, + (int)st2.st_size, st2.st_mode); + fprintf(stdout, " time: %s\n", ctime(&st2.st_atime)); + fprintf(stdout, "Earlier stat: %s, Size = %d, mode = %04X\n", file, + (int)st1.st_size, st1.st_mode); + fprintf(stdout, " time: %s\n", ctime(&st1.st_atime)); + + /* Now, make a directory ... */ + + fprintf(stdout, "Making directory smb://samba/public/make-dir\n"); + + if (smbc_mkdir("smb://samba/public/make-dir", 0666) < 0) { + + fprintf(stderr, "Error making directory: smb://samba/public/make-dir: %s\n", + strerror(errno)); + + if (errno == EEXIST) { /* Try to delete the directory */ + + fprintf(stdout, "Trying to delete directory: smb://samba/public/make-dir\n"); + + if (smbc_rmdir("smb://samba/public/make-dir") < 0) { /* Error */ + + fprintf(stderr, "Error removing directory: smb://samba/public/make-dir: %s\n", strerror(errno)); + + exit(0); + + } + + fprintf(stdout, "Making directory: smb://samba/public/make-dir\n"); + + if (smbc_mkdir("smb://samba/public/make-dir", 666) < 0) { + + fprintf(stderr, "Error making directory: smb://samba/public/make-dir: %s\n", + strerror(errno)); + + fprintf(stderr, "I give up!\n"); + + exit(1); + + } + + } + + exit(0); + + } + + fprintf(stdout, "Made dir: make-dir\n"); + return 0; +} diff --git a/examples/libsmbclient/teststat.c b/examples/libsmbclient/teststat.c new file mode 100644 index 0000000000..86c69e4e2c --- /dev/null +++ b/examples/libsmbclient/teststat.c @@ -0,0 +1,71 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <time.h> +#include <libsmbclient.h> +#include "get_auth_data_fn.h" + + +int main(int argc, char * argv[]) +{ + int debug = 0; + char buffer[16384]; + char mtime[32]; + char ctime[32]; + char atime[32]; + char * pSmbPath = NULL; + char * pLocalPath = NULL; + struct stat st; + + if (argc == 1) + { + pSmbPath = "smb://RANDOM/Public/small"; + pLocalPath = "/random/home/samba/small"; + } + else if (argc == 2) + { + pSmbPath = argv[1]; + pLocalPath = NULL; + } + else if (argc == 3) + { + pSmbPath = argv[1]; + pLocalPath = argv[2]; + } + else + { + printf("usage: " + "%s [ smb://path/to/file [ /nfs/or/local/path/to/file ] ]\n", + argv[0]); + return 1; + } + + smbc_init(get_auth_data_fn, debug); + + if (smbc_stat(pSmbPath, &st) < 0) + { + perror("smbc_stat"); + return 1; + } + + printf("\nSAMBA\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n", + st.st_mtime, ctime_r(&st.st_mtime, mtime), + st.st_ctime, ctime_r(&st.st_ctime, ctime), + st.st_atime, ctime_r(&st.st_atime, atime)); + + if (pLocalPath != NULL) + { + if (stat(pLocalPath, &st) < 0) + { + perror("stat"); + return 1; + } + + printf("LOCAL\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n", + st.st_mtime, ctime_r(&st.st_mtime, mtime), + st.st_ctime, ctime_r(&st.st_ctime, ctime), + st.st_atime, ctime_r(&st.st_atime, atime)); + } + + return 0; +} diff --git a/examples/libsmbclient/teststat2.c b/examples/libsmbclient/teststat2.c new file mode 100644 index 0000000000..d1cdf28501 --- /dev/null +++ b/examples/libsmbclient/teststat2.c @@ -0,0 +1,72 @@ +#include <libsmbclient.h> +#include <sys/stat.h> +#include <string.h> +#include <stdio.h> +#include <time.h> +#include "get_auth_data_fn.h" + +/* + * This test is intended to ensure that the timestamps returned by + * libsmbclient are the same as timestamps returned by the local system. To + * test this, we assume a working Samba environment, and and access the same + * file via SMB and locally (or NFS). + * + */ + + +static int gettime(const char * pUrl, + const char * pLocalPath); + + +int main(int argc, char* argv[]) +{ + if(argc != 3) + { + printf("usage: %s <file_url> <file_localpath>\n", argv[0]); + return 1; + } + + gettime(argv[1], argv[2]); + return 0; +} + + +static int gettime(const char * pUrl, + const char * pLocalPath) +{ + //char *pSmbPath = 0; + struct stat st; + char mtime[32]; + char ctime[32]; + char atime[32]; + + smbc_init(get_auth_data_fn, 0); + + if (smbc_stat(pUrl, &st) < 0) + { + perror("smbc_stat"); + return 1; + } + + printf("SAMBA\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n", + st.st_mtime, ctime_r(&st.st_mtime, mtime), + st.st_ctime, ctime_r(&st.st_ctime, ctime), + st.st_atime, ctime_r(&st.st_atime, atime)); + + + // check the stat on this file + if (stat(pLocalPath, &st) < 0) + { + perror("stat"); + return 1; + } + + printf("LOCAL\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n", + st.st_mtime, ctime_r(&st.st_mtime, mtime), + st.st_ctime, ctime_r(&st.st_ctime, ctime), + st.st_atime, ctime_r(&st.st_atime, atime)); + + + return 0; +} + diff --git a/examples/libsmbclient/teststat3.c b/examples/libsmbclient/teststat3.c new file mode 100644 index 0000000000..26348b335c --- /dev/null +++ b/examples/libsmbclient/teststat3.c @@ -0,0 +1,78 @@ +#include <libsmbclient.h> +#include <sys/stat.h> +#include <string.h> +#include <stdio.h> +#include <time.h> +#include "get_auth_data_fn.h" + +/* + * This test is intended to ensure that the timestamps returned by + * libsmbclient using smbc_stat() are the same as those returned by + * smbc_fstat(). + */ + + +int main(int argc, char* argv[]) +{ + int fd; + struct stat st1; + struct stat st2; + char mtime[32]; + char ctime[32]; + char atime[32]; + char * pUrl = argv[1]; + + if(argc != 2) + { + printf("usage: %s <file_url>\n", argv[0]); + return 1; + } + + + smbc_init(get_auth_data_fn, 0); + + if (smbc_stat(pUrl, &st1) < 0) + { + perror("smbc_stat"); + return 1; + } + + if ((fd = smbc_open(pUrl, O_RDONLY, 0)) < 0) + { + perror("smbc_open"); + return 1; + } + + if (smbc_fstat(fd, &st2) < 0) + { + perror("smbc_fstat"); + return 1; + } + + smbc_close(fd); + +#define COMPARE(name, field) \ + if (st1.field != st2.field) \ + { \ + printf("Field " name " MISMATCH: st1=%lu, st2=%lu\n", \ + (unsigned long) st1.field, \ + (unsigned long) st2.field); \ + } + + COMPARE("st_dev", st_dev); + COMPARE("st_ino", st_ino); + COMPARE("st_mode", st_mode); + COMPARE("st_nlink", st_nlink); + COMPARE("st_uid", st_uid); + COMPARE("st_gid", st_gid); + COMPARE("st_rdev", st_rdev); + COMPARE("st_size", st_size); + COMPARE("st_blksize", st_blksize); + COMPARE("st_blocks", st_blocks); + COMPARE("st_atime", st_atime); + COMPARE("st_mtime", st_mtime); + COMPARE("st_ctime", st_ctime); + + return 0; +} + diff --git a/examples/libsmbclient/testtruncate.c b/examples/libsmbclient/testtruncate.c new file mode 100644 index 0000000000..8882acd85d --- /dev/null +++ b/examples/libsmbclient/testtruncate.c @@ -0,0 +1,82 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <time.h> +#include <errno.h> +#include <libsmbclient.h> +#include "get_auth_data_fn.h" + + +int main(int argc, char * argv[]) +{ + int fd; + int ret; + int debug = 0; + int savedErrno; + char buffer[128]; + char * pSmbPath = NULL; + char * pLocalPath = NULL; + struct stat st; + + if (argc != 2) + { + printf("usage: " + "%s smb://path/to/file\n", + argv[0]); + return 1; + } + + smbc_init(get_auth_data_fn, debug); + + if ((fd = smbc_open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0)) < 0) + { + perror("smbc_open"); + return 1; + } + + strcpy(buffer, "Hello world.\nThis is a test.\n"); + + ret = smbc_write(fd, buffer, strlen(buffer)); + savedErrno = errno; + smbc_close(fd); + + if (ret < 0) + { + errno = savedErrno; + perror("write"); + } + + if (smbc_stat(argv[1], &st) < 0) + { + perror("smbc_stat"); + return 1; + } + + printf("Original size: %lu\n", (unsigned long) st.st_size); + + if ((fd = smbc_open(argv[1], O_WRONLY, 0)) < 0) + { + perror("smbc_open"); + return 1; + } + + ret = smbc_ftruncate(fd, 13); + savedErrno = errno; + smbc_close(fd); + if (ret < 0) + { + errno = savedErrno; + perror("smbc_ftruncate"); + return 1; + } + + if (smbc_stat(argv[1], &st) < 0) + { + perror("smbc_stat"); + return 1; + } + + printf("New size: %lu\n", (unsigned long) st.st_size); + + return 0; +} diff --git a/examples/libsmbclient/testutime.c b/examples/libsmbclient/testutime.c new file mode 100644 index 0000000000..2ad395f862 --- /dev/null +++ b/examples/libsmbclient/testutime.c @@ -0,0 +1,77 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <time.h> +#include <libsmbclient.h> +#include "get_auth_data_fn.h" + + +int main(int argc, char * argv[]) +{ + int ret; + int debug = 0; + char buffer[16384]; + char mtime[32]; + char ctime[32]; + char atime[32]; + char * pSmbPath = NULL; + time_t t = time(NULL); + struct tm tm; + struct stat st; + struct utimbuf utimbuf; + + if (argc == 1) + { + pSmbPath = "smb://RANDOM/Public/small"; + } + else if (argc == 2) + { + pSmbPath = argv[1]; + } + else if (argc == 3) + { + pSmbPath = argv[1]; + t = (time_t) strtol(argv[2], NULL, 10); + } + else + { + printf("usage: " + "%s [ smb://path/to/file [ mtime ] ]\n", + argv[0]); + return 1; + } + + smbc_init(get_auth_data_fn, debug); + + if (smbc_stat(pSmbPath, &st) < 0) + { + perror("smbc_stat"); + return 1; + } + + printf("Before\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n", + st.st_mtime, ctime_r(&st.st_mtime, mtime), + st.st_ctime, ctime_r(&st.st_ctime, ctime), + st.st_atime, ctime_r(&st.st_atime, atime)); + + utimbuf.actime = t; /* unchangable (wont change) */ + utimbuf.modtime = t; /* this one should succeed */ + if (smbc_utime(pSmbPath, &utimbuf) < 0) + { + perror("smbc_utime"); + return 1; + } + + if (smbc_stat(pSmbPath, &st) < 0) + { + perror("smbc_stat"); + return 1; + } + + printf("After\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n", + st.st_mtime, ctime_r(&st.st_mtime, mtime), + st.st_ctime, ctime_r(&st.st_ctime, ctime), + st.st_atime, ctime_r(&st.st_atime, atime)); + + return 0; +} diff --git a/examples/libsmbclient/testwrite.c b/examples/libsmbclient/testwrite.c new file mode 100644 index 0000000000..780f0e95da --- /dev/null +++ b/examples/libsmbclient/testwrite.c @@ -0,0 +1,69 @@ +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <time.h> +#include <errno.h> +#include <libsmbclient.h> +#include "get_auth_data_fn.h" + + +int main(int argc, char * argv[]) +{ + int i; + int fd; + int ret; + int debug = 0; + int mode = 0666; + int savedErrno; + char buffer[2048]; + char path[2048]; + char * p; + time_t t0; + time_t t1; + struct stat st; + + smbc_init(get_auth_data_fn, debug); + + printf("CAUTION: This program will overwrite a file. " + "Press ENTER to continue."); + fgets(buffer, sizeof(buffer), stdin); + + + for (;;) + { + fprintf(stdout, "\nPath: "); + *path = '\0'; + fgets(path, sizeof(path) - 1, stdin); + if (strlen(path) == 0) + { + return 0; + } + + p = path + strlen(path) - 1; + if (*p == '\n') + { + *p = '\0'; + } + + if ((fd = smbc_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0)) < 0) + { + perror("smbc_open"); + continue; + } + + strcpy(buffer, "Hello world\n"); + + ret = smbc_write(fd, buffer, strlen(buffer)); + savedErrno = errno; + smbc_close(fd); + + if (ret < 0) + { + errno = savedErrno; + perror("write"); + } + } + + return 0; +} diff --git a/examples/libsmbclient/tree.c b/examples/libsmbclient/tree.c new file mode 100644 index 0000000000..6e34cd0562 --- /dev/null +++ b/examples/libsmbclient/tree.c @@ -0,0 +1,814 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB client GTK+ tree-based application + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2001 + Copyright (C) John Terpstra 2001 + + 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/>. +*/ + +/* example-gtk+ application, ripped off from the gtk+ tree.c sample */ + +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <gtk/gtk.h> +#include "libsmbclient.h" + +static GtkWidget *clist; + +struct tree_data { + + guint32 type; /* Type of tree item, an SMBC_TYPE */ + char name[256]; /* May need to change this later */ + +}; + +void error_message(gchar *message) { + + GtkWidget *dialog, *label, *okay_button; + + /* Create the widgets */ + + dialog = gtk_dialog_new(); + gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); + label = gtk_label_new (message); + okay_button = gtk_button_new_with_label("Okay"); + + /* Ensure that the dialog box is destroyed when the user clicks ok. */ + + gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + GTK_OBJECT(dialog)); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), + okay_button); + + /* Add the label, and show everything we've added to the dialog. */ + + gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), + label); + gtk_widget_show_all (dialog); +} + +/* + * We are given a widget, and we want to retrieve its URL so we + * can do a directory listing. + * + * We walk back up the tree, picking up pieces until we hit a server or + * workgroup type and return a path from there + */ + +static char path_string[1024]; + +char *get_path(GtkWidget *item) +{ + GtkWidget *p = item; + struct tree_data *pd; + char *comps[1024]; /* We keep pointers to the components here */ + int i = 0, j, level,type; + + /* Walk back up the tree, getting the private data */ + + level = GTK_TREE(item->parent)->level; + + /* Pick up this item's component info */ + + pd = (struct tree_data *)gtk_object_get_user_data(GTK_OBJECT(item)); + + comps[i++] = pd->name; + type = pd->type; + + while (level > 0 && type != SMBC_SERVER && type != SMBC_WORKGROUP) { + + /* Find the parent and extract the data etc ... */ + + p = GTK_WIDGET(p->parent); + p = GTK_WIDGET(GTK_TREE(p)->tree_owner); + + pd = (struct tree_data *)gtk_object_get_user_data(GTK_OBJECT(p)); + + level = GTK_TREE(item->parent)->level; + + comps[i++] = pd->name; + type = pd->type; + + } + + /* + * Got a list of comps now, should check that we did not hit a workgroup + * when we got other things as well ... Later + * + * Now, build the path + */ + + snprintf(path_string, sizeof(path_string), "smb:/"); + + for (j = i - 1; j >= 0; j--) { + + strncat(path_string, "/", sizeof(path_string) - strlen(path_string)); + strncat(path_string, comps[j], sizeof(path_string) - strlen(path_string)); + + } + + fprintf(stdout, "Path string = %s\n", path_string); + + return path_string; + +} + +struct tree_data *make_tree_data(guint32 type, const char *name) +{ + struct tree_data *p = (struct tree_data *)malloc(sizeof(struct tree_data)); + + if (p) { + + p->type = type; + strncpy(p->name, name, sizeof(p->name)); + + } + + return p; + +} + +/* Note that this is called every time the user clicks on an item, + whether it is already selected or not. */ +static void cb_select_child (GtkWidget *root_tree, GtkWidget *child, + GtkWidget *subtree) +{ + gint dh, err, dirlen; + char dirbuf[512]; + struct smbc_dirent *dirp; + struct stat st1; + char path[1024], path1[1024]; + + g_print ("select_child called for root tree %p, subtree %p, child %p\n", + root_tree, subtree, child); + + /* Now, figure out what it is, and display it in the clist ... */ + + gtk_clist_clear(GTK_CLIST(clist)); /* Clear the CLIST */ + + /* Now, get the private data for the subtree */ + + strncpy(path, get_path(child), 1024); + + if ((dh = smbc_opendir(path)) < 0) { /* Handle error */ + + g_print("cb_select_child: Could not open dir %s, %s\n", path, + strerror(errno)); + + gtk_main_quit(); + + return; + + } + + while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf, + sizeof(dirbuf))) != 0) { + + if (err < 0) { + + g_print("cb_select_child: Could not read dir %s, %s\n", path, + strerror(errno)); + + gtk_main_quit(); + + return; + + } + + dirp = (struct smbc_dirent *)dirbuf; + + while (err > 0) { + gchar col1[128], col2[128], col3[128], col4[128]; + gchar *rowdata[4] = {col1, col2, col3, col4}; + + dirlen = dirp->dirlen; + + /* Format each of the items ... */ + + strncpy(col1, dirp->name, 128); + + col2[0] = col3[0] = col4[0] = (char)0; + + switch (dirp->smbc_type) { + + case SMBC_WORKGROUP: + + break; + + case SMBC_SERVER: + + strncpy(col2, (dirp->comment?dirp->comment:""), 128); + + break; + + case SMBC_FILE_SHARE: + + strncpy(col2, (dirp->comment?dirp->comment:""), 128); + + break; + + case SMBC_PRINTER_SHARE: + + strncpy(col2, (dirp->comment?dirp->comment:""), 128); + break; + + case SMBC_COMMS_SHARE: + + break; + + case SMBC_IPC_SHARE: + + break; + + case SMBC_DIR: + case SMBC_FILE: + + /* Get stats on the file/dir and see what we have */ + + if ((strcmp(dirp->name, ".") != 0) && + (strcmp(dirp->name, "..") != 0)) { + + strncpy(path1, path, sizeof(path1)); + strncat(path1, "/", sizeof(path) - strlen(path)); + strncat(path1, dirp->name, sizeof(path) - strlen(path)); + + if (smbc_stat(path1, &st1) < 0) { + + if (errno != EBUSY) { + + g_print("cb_select_child: Could not stat file %s, %s\n", path1, + strerror(errno)); + + gtk_main_quit(); + + return; + + } + else { + + strncpy(col2, "Device or resource busy", sizeof(col2)); + + } + } + else { + /* Now format each of the relevant things ... */ + + snprintf(col2, sizeof(col2), "%c%c%c%c%c%c%c%c%c(%0X)", + (st1.st_mode&S_IRUSR?'r':'-'), + (st1.st_mode&S_IWUSR?'w':'-'), + (st1.st_mode&S_IXUSR?'x':'-'), + (st1.st_mode&S_IRGRP?'r':'-'), + (st1.st_mode&S_IWGRP?'w':'-'), + (st1.st_mode&S_IXGRP?'x':'-'), + (st1.st_mode&S_IROTH?'r':'-'), + (st1.st_mode&S_IWOTH?'w':'-'), + (st1.st_mode&S_IXOTH?'x':'-'), + st1.st_mode); + snprintf(col3, sizeof(col3), "%u", st1.st_size); + snprintf(col4, sizeof(col4), "%s", ctime(&st1.st_mtime)); + } + } + + break; + + default: + + break; + } + + gtk_clist_append(GTK_CLIST(clist), rowdata); + + dirp = (struct smbc_dirent *) ((char *) dirp + dirlen); + err -= dirlen; + + } + + } + +} + +/* Note that this is never called */ +static void cb_unselect_child( GtkWidget *root_tree, + GtkWidget *child, + GtkWidget *subtree ) +{ + g_print ("unselect_child called for root tree %p, subtree %p, child %p\n", + root_tree, subtree, child); +} + +/* for all the GtkItem:: and GtkTreeItem:: signals */ +static void cb_itemsignal( GtkWidget *item, + gchar *signame ) +{ + GtkWidget *real_tree, *aitem, *subtree; + gchar *name; + GtkLabel *label; + gint dh, err, dirlen, level; + char dirbuf[512]; + struct smbc_dirent *dirp; + + label = GTK_LABEL (GTK_BIN (item)->child); + /* Get the text of the label */ + gtk_label_get (label, &name); + + level = GTK_TREE(item->parent)->level; + + /* Get the level of the tree which the item is in */ + g_print ("%s called for item %s->%p, level %d\n", signame, name, + item, GTK_TREE (item->parent)->level); + + real_tree = GTK_TREE_ITEM_SUBTREE(item); /* Get the subtree */ + + if (strncmp(signame, "expand", 6) == 0) { /* Expand called */ + char server[128]; + + if ((dh = smbc_opendir(get_path(item))) < 0) { /* Handle error */ + gchar errmsg[256]; + + g_print("cb_itemsignal: Could not open dir %s, %s\n", get_path(item), + strerror(errno)); + + snprintf(errmsg, sizeof(errmsg), "cb_itemsignal: Could not open dir %s, %s\n", get_path(item), strerror(errno)); + + error_message(errmsg); + + /* gtk_main_quit();*/ + + return; + + } + + while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf, + sizeof(dirbuf))) != 0) { + + if (err < 0) { /* An error, report it */ + gchar errmsg[256]; + + g_print("cb_itemsignal: Could not read dir smbc://, %s\n", + strerror(errno)); + + snprintf(errmsg, sizeof(errmsg), "cb_itemsignal: Could not read dir smbc://, %s\n", strerror(errno)); + + error_message(errmsg); + + /* gtk_main_quit();*/ + + return; + + } + + dirp = (struct smbc_dirent *)dirbuf; + + while (err > 0) { + struct tree_data *my_data; + + dirlen = dirp->dirlen; + + my_data = make_tree_data(dirp->smbc_type, dirp->name); + + if (!my_data) { + + g_print("Could not allocate space for tree_data: %s\n", + dirp->name); + + gtk_main_quit(); + return; + + } + + aitem = gtk_tree_item_new_with_label(dirp->name); + + /* Connect all GtkItem:: and GtkTreeItem:: signals */ + gtk_signal_connect (GTK_OBJECT(aitem), "select", + GTK_SIGNAL_FUNC(cb_itemsignal), "select"); + gtk_signal_connect (GTK_OBJECT(aitem), "deselect", + GTK_SIGNAL_FUNC(cb_itemsignal), "deselect"); + gtk_signal_connect (GTK_OBJECT(aitem), "toggle", + GTK_SIGNAL_FUNC(cb_itemsignal), "toggle"); + gtk_signal_connect (GTK_OBJECT(aitem), "expand", + GTK_SIGNAL_FUNC(cb_itemsignal), "expand"); + gtk_signal_connect (GTK_OBJECT(aitem), "collapse", + GTK_SIGNAL_FUNC(cb_itemsignal), "collapse"); + /* Add it to the parent tree */ + gtk_tree_append (GTK_TREE(real_tree), aitem); + + gtk_widget_show (aitem); + + gtk_object_set_user_data(GTK_OBJECT(aitem), (gpointer)my_data); + + fprintf(stdout, "Added: %s, len: %u\n", dirp->name, dirlen); + + if (dirp->smbc_type != SMBC_FILE && + dirp->smbc_type != SMBC_IPC_SHARE && + (strcmp(dirp->name, ".") != 0) && + (strcmp(dirp->name, "..") !=0)){ + + subtree = gtk_tree_new(); + gtk_tree_item_set_subtree(GTK_TREE_ITEM(aitem), subtree); + + gtk_signal_connect(GTK_OBJECT(subtree), "select_child", + GTK_SIGNAL_FUNC(cb_select_child), real_tree); + gtk_signal_connect(GTK_OBJECT(subtree), "unselect_child", + GTK_SIGNAL_FUNC(cb_unselect_child), real_tree); + + } + + dirp = (struct smbc_dirent *) ((char *) dirp + dirlen); + err -= dirlen; + + } + + } + + smbc_closedir(dh); + + } + else if (strncmp(signame, "collapse", 8) == 0) { + GtkWidget *subtree = gtk_tree_new(); + + gtk_tree_remove_items(GTK_TREE(real_tree), GTK_TREE(real_tree)->children); + + gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree); + + gtk_signal_connect (GTK_OBJECT(subtree), "select_child", + GTK_SIGNAL_FUNC(cb_select_child), real_tree); + gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child", + GTK_SIGNAL_FUNC(cb_unselect_child), real_tree); + + } + +} + +static void cb_selection_changed( GtkWidget *tree ) +{ + GList *i; + + g_print ("selection_change called for tree %p\n", tree); + g_print ("selected objects are:\n"); + + i = GTK_TREE_SELECTION(tree); + while (i){ + gchar *name; + GtkLabel *label; + GtkWidget *item; + + /* Get a GtkWidget pointer from the list node */ + item = GTK_WIDGET (i->data); + label = GTK_LABEL (GTK_BIN (item)->child); + gtk_label_get (label, &name); + g_print ("\t%s on level %d\n", name, GTK_TREE + (item->parent)->level); + i = i->next; + } +} + +/* + * Expand or collapse the whole network ... + */ +static void cb_wholenet(GtkWidget *item, gchar *signame) +{ + GtkWidget *real_tree, *aitem, *subtree; + gchar *name; + GtkLabel *label; + gint dh, err, dirlen; + char dirbuf[512]; + struct smbc_dirent *dirp; + + label = GTK_LABEL (GTK_BIN (item)->child); + gtk_label_get (label, &name); + g_print ("%s called for item %s->%p, level %d\n", signame, name, + item, GTK_TREE (item->parent)->level); + + real_tree = GTK_TREE_ITEM_SUBTREE(item); /* Get the subtree */ + + if (strncmp(signame, "expand", 6) == 0) { /* Expand called */ + + if ((dh = smbc_opendir("smb://")) < 0) { /* Handle error */ + + g_print("cb_wholenet: Could not open dir smbc://, %s\n", + strerror(errno)); + + gtk_main_quit(); + + return; + + } + + while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf, + sizeof(dirbuf))) != 0) { + + if (err < 0) { /* An error, report it */ + + g_print("cb_wholenet: Could not read dir smbc://, %s\n", + strerror(errno)); + + gtk_main_quit(); + + return; + + } + + dirp = (struct smbc_dirent *)dirbuf; + + while (err > 0) { + struct tree_data *my_data; + + dirlen = dirp->dirlen; + + my_data = make_tree_data(dirp->smbc_type, dirp->name); + + aitem = gtk_tree_item_new_with_label(dirp->name); + + /* Connect all GtkItem:: and GtkTreeItem:: signals */ + gtk_signal_connect (GTK_OBJECT(aitem), "select", + GTK_SIGNAL_FUNC(cb_itemsignal), "select"); + gtk_signal_connect (GTK_OBJECT(aitem), "deselect", + GTK_SIGNAL_FUNC(cb_itemsignal), "deselect"); + gtk_signal_connect (GTK_OBJECT(aitem), "toggle", + GTK_SIGNAL_FUNC(cb_itemsignal), "toggle"); + gtk_signal_connect (GTK_OBJECT(aitem), "expand", + GTK_SIGNAL_FUNC(cb_itemsignal), "expand"); + gtk_signal_connect (GTK_OBJECT(aitem), "collapse", + GTK_SIGNAL_FUNC(cb_itemsignal), "collapse"); + + gtk_tree_append (GTK_TREE(real_tree), aitem); + /* Show it - this can be done at any time */ + gtk_widget_show (aitem); + + gtk_object_set_user_data(GTK_OBJECT(aitem), (gpointer)my_data); + + fprintf(stdout, "Added: %s, len: %u\n", dirp->name, dirlen); + + subtree = gtk_tree_new(); + + gtk_tree_item_set_subtree(GTK_TREE_ITEM(aitem), subtree); + + gtk_signal_connect(GTK_OBJECT(subtree), "select_child", + GTK_SIGNAL_FUNC(cb_select_child), real_tree); + gtk_signal_connect(GTK_OBJECT(subtree), "unselect_child", + GTK_SIGNAL_FUNC(cb_unselect_child), real_tree); + + dirp = (struct smbc_dirent *) ((char *) dirp + dirlen); + err -= dirlen; + + } + + } + + smbc_closedir(dh); + + } + else { /* Must be collapse ... FIXME ... */ + GtkWidget *subtree = gtk_tree_new(); + + gtk_tree_remove_items(GTK_TREE(real_tree), GTK_TREE(real_tree)->children); + + gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree); + + gtk_signal_connect (GTK_OBJECT(subtree), "select_child", + GTK_SIGNAL_FUNC(cb_select_child), real_tree); + gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child", + GTK_SIGNAL_FUNC(cb_unselect_child), real_tree); + + + } + +} + +/* Should put up a dialog box to ask the user for username and password */ + +static void +auth_fn(const char *server, const char *share, + char *workgroup, int wgmaxlen, char *username, int unmaxlen, + char *password, int pwmaxlen) +{ + + strncpy(username, "test", unmaxlen); + strncpy(password, "test", pwmaxlen); + +} + +static char *col_titles[] = { + "Name", "Attributes", "Size", "Modification Date", +}; + +int main( int argc, + char *argv[] ) +{ + GtkWidget *window, *scrolled_win, *scrolled_win2, *tree; + GtkWidget *subtree, *item, *main_hbox, *r_pane, *l_pane; + gint err, dh; + gint i; + char dirbuf[512]; + struct smbc_dirent *dirp; + + gtk_init (&argc, &argv); + + /* Init the smbclient library */ + + err = smbc_init(auth_fn, 10); + + /* Print an error response ... */ + + if (err < 0) { + + fprintf(stderr, "smbc_init returned %s (%i)\nDo you have a ~/.smb/smb.conf file?\n", strerror(errno), errno); + exit(1); + + } + + /* a generic toplevel window */ + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name(window, "main browser window"); + gtk_signal_connect (GTK_OBJECT(window), "delete_event", + GTK_SIGNAL_FUNC (gtk_main_quit), NULL); + gtk_window_set_title(GTK_WINDOW(window), "The Linux Windows Network Browser"); + gtk_widget_set_usize(GTK_WIDGET(window), 750, -1); + gtk_container_set_border_width (GTK_CONTAINER(window), 5); + + gtk_widget_show (window); + + /* A container for the two panes ... */ + + main_hbox = gtk_hbox_new(FALSE, 1); + gtk_container_border_width(GTK_CONTAINER(main_hbox), 1); + gtk_container_add(GTK_CONTAINER(window), main_hbox); + + gtk_widget_show(main_hbox); + + l_pane = gtk_hpaned_new(); + gtk_paned_gutter_size(GTK_PANED(l_pane), (GTK_PANED(l_pane))->handle_size); + r_pane = gtk_hpaned_new(); + gtk_paned_gutter_size(GTK_PANED(r_pane), (GTK_PANED(r_pane))->handle_size); + gtk_container_add(GTK_CONTAINER(main_hbox), l_pane); + gtk_widget_show(l_pane); + + /* A generic scrolled window */ + scrolled_win = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_widget_set_usize (scrolled_win, 150, 200); + gtk_container_add (GTK_CONTAINER(l_pane), scrolled_win); + gtk_widget_show (scrolled_win); + + /* Another generic scrolled window */ + scrolled_win2 = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win2), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_widget_set_usize (scrolled_win2, 150, 200); + gtk_paned_add2 (GTK_PANED(l_pane), scrolled_win2); + gtk_widget_show (scrolled_win2); + + /* Create the root tree */ + tree = gtk_tree_new(); + g_print ("root tree is %p\n", tree); + /* connect all GtkTree:: signals */ + gtk_signal_connect (GTK_OBJECT(tree), "select_child", + GTK_SIGNAL_FUNC(cb_select_child), tree); + gtk_signal_connect (GTK_OBJECT(tree), "unselect_child", + GTK_SIGNAL_FUNC(cb_unselect_child), tree); + gtk_signal_connect (GTK_OBJECT(tree), "selection_changed", + GTK_SIGNAL_FUNC(cb_selection_changed), tree); + /* Add it to the scrolled window */ + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_win), + tree); + /* Set the selection mode */ + gtk_tree_set_selection_mode (GTK_TREE(tree), + GTK_SELECTION_MULTIPLE); + /* Show it */ + gtk_widget_show (tree); + + /* Now, create a clist and attach it to the second pane */ + + clist = gtk_clist_new_with_titles(4, col_titles); + + gtk_container_add (GTK_CONTAINER(scrolled_win2), clist); + + gtk_widget_show(clist); + + /* Now, build the top level display ... */ + + if ((dh = smbc_opendir("smb://")) < 0) { + + fprintf(stderr, "Could not list workgroups: smb://: %s\n", + strerror(errno)); + + exit(1); + + } + + /* Create a tree item for Whole Network */ + + item = gtk_tree_item_new_with_label ("Whole Network"); + /* Connect all GtkItem:: and GtkTreeItem:: signals */ + gtk_signal_connect (GTK_OBJECT(item), "select", + GTK_SIGNAL_FUNC(cb_itemsignal), "select"); + gtk_signal_connect (GTK_OBJECT(item), "deselect", + GTK_SIGNAL_FUNC(cb_itemsignal), "deselect"); + gtk_signal_connect (GTK_OBJECT(item), "toggle", + GTK_SIGNAL_FUNC(cb_itemsignal), "toggle"); + gtk_signal_connect (GTK_OBJECT(item), "expand", + GTK_SIGNAL_FUNC(cb_wholenet), "expand"); + gtk_signal_connect (GTK_OBJECT(item), "collapse", + GTK_SIGNAL_FUNC(cb_wholenet), "collapse"); + /* Add it to the parent tree */ + gtk_tree_append (GTK_TREE(tree), item); + /* Show it - this can be done at any time */ + gtk_widget_show (item); + + subtree = gtk_tree_new(); /* A subtree for Whole Network */ + + gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree); + + gtk_signal_connect (GTK_OBJECT(subtree), "select_child", + GTK_SIGNAL_FUNC(cb_select_child), tree); + gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child", + GTK_SIGNAL_FUNC(cb_unselect_child), tree); + + /* Now, get the items in smb:/// and add them to the tree */ + + while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf, + sizeof(dirbuf))) != 0) { + + if (err < 0) { /* Handle the error */ + + fprintf(stderr, "Could not read directory for smbc:///: %s\n", + strerror(errno)); + + exit(1); + + } + + dirp = (struct smbc_dirent *)dirbuf; + + fprintf(stdout, "Dir len: %u\n", err); + + while (err > 0) { /* Extract each entry and make a sub-tree */ + struct tree_data *my_data; + int dirlen = dirp->dirlen; + + my_data = make_tree_data(dirp->smbc_type, dirp->name); + + item = gtk_tree_item_new_with_label(dirp->name); + /* Connect all GtkItem:: and GtkTreeItem:: signals */ + gtk_signal_connect (GTK_OBJECT(item), "select", + GTK_SIGNAL_FUNC(cb_itemsignal), "select"); + gtk_signal_connect (GTK_OBJECT(item), "deselect", + GTK_SIGNAL_FUNC(cb_itemsignal), "deselect"); + gtk_signal_connect (GTK_OBJECT(item), "toggle", + GTK_SIGNAL_FUNC(cb_itemsignal), "toggle"); + gtk_signal_connect (GTK_OBJECT(item), "expand", + GTK_SIGNAL_FUNC(cb_itemsignal), "expand"); + gtk_signal_connect (GTK_OBJECT(item), "collapse", + GTK_SIGNAL_FUNC(cb_itemsignal), "collapse"); + /* Add it to the parent tree */ + gtk_tree_append (GTK_TREE(tree), item); + /* Show it - this can be done at any time */ + gtk_widget_show (item); + + gtk_object_set_user_data(GTK_OBJECT(item), (gpointer)my_data); + + fprintf(stdout, "Added: %s, len: %u\n", dirp->name, dirlen); + + subtree = gtk_tree_new(); + + gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree); + + gtk_signal_connect (GTK_OBJECT(subtree), "select_child", + GTK_SIGNAL_FUNC(cb_select_child), tree); + gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child", + GTK_SIGNAL_FUNC(cb_unselect_child), tree); + + dirp = (struct smbc_dirent *) ((char *) dirp + dirlen); + err -= dirlen; + + } + + } + + smbc_closedir(dh); /* FIXME, check for error :-) */ + + /* Show the window and loop endlessly */ + gtk_main(); + return 0; +} +/* example-end */ diff --git a/examples/logon/genlogon/genlogon.pl b/examples/logon/genlogon/genlogon.pl new file mode 100644 index 0000000000..4799ac8452 --- /dev/null +++ b/examples/logon/genlogon/genlogon.pl @@ -0,0 +1,71 @@ +#!/usr/bin/perl +# +# genlogon.pl +# +# Perl script to generate user logon scripts on the fly, when users +# connect from a Windows client. This script should be called from smb.conf +# with the %U, %G and %L parameters. I.e: +# +# root preexec = genlogon.pl %U %G %L +# +# The script generated will perform +# the following: +# +# 1. Log the user connection to /var/log/samba/netlogon.log +# 2. Set the PC's time to the Linux server time (which is maintained +# daily to the National Institute of Standard's Atomic clock on the +# internet. +# 3. Connect the user's home drive to H: (H for Home). +# 4. Connect common drives that everyone uses. +# 5. Connect group-specific drives for certain user groups. +# 6. Connect user-specific drives for certain users. +# 7. Connect network printers. + +# Log client connection +#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +open LOG, ">>/var/log/samba/netlogon.log"; +print LOG "$mon/$mday/$year $hour:$min:$sec - User $ARGV[0] logged into $ARGV[1]\n"; +close LOG; + +# Start generating logon script +open LOGON, ">/shared/netlogon/$ARGV[0].bat"; +print LOGON "\@ECHO OFF\r\n"; + +# Connect shares just use by Software Development group +if ($ARGV[1] eq "SOFTDEV" || $ARGV[0] eq "softdev") +{ + print LOGON "NET USE M: \\\\$ARGV[2]\\SOURCE\r\n"; +} + +# Connect shares just use by Technical Support staff +if ($ARGV[1] eq "SUPPORT" || $ARGV[0] eq "support") +{ + print LOGON "NET USE S: \\\\$ARGV[2]\\SUPPORT\r\n"; +} + +# Connect shares just used by Administration staff +if ($ARGV[1] eq "ADMIN" || $ARGV[0] eq "admin") +{ + print LOGON "NET USE L: \\\\$ARGV[2]\\ADMIN\r\n"; + print LOGON "NET USE K: \\\\$ARGV[2]\\MKTING\r\n"; +} + +# Now connect Printers. We handle just two or three users a little +# differently, because they are the exceptions that have desktop +# printers on LPT1: - all other user's go to the LaserJet on the +# server. +if ($ARGV[0] eq 'jim' + || $ARGV[0] eq 'yvonne') +{ + print LOGON "NET UsE LPT2: \\\\$ARGV[2]\\LJET3\r\n"; + print LOGON "NET USE LPT3: \\\\$ARGV[2]\\FAXQ\r\n"; +} +else +{ + print LOGON "NET USE LPT1: \\\\$ARGV[2]\\LJET3\r\n"; + print LOGON "NET USE LPT3: \\\\$ARGV[2]\\FAXQ\r\n"; +} + +# All done! Close the output file. +close LOGON; diff --git a/examples/logon/mklogon/mklogon.conf b/examples/logon/mklogon/mklogon.conf new file mode 100644 index 0000000000..b04708977c --- /dev/null +++ b/examples/logon/mklogon/mklogon.conf @@ -0,0 +1,78 @@ +# Mapping should be kept in the form +# username(USER) or groupname(WEBUSERS) = driveletter (W:), samba share name (WEB) +# ie. user = W:,WEB or webusers = W:,WEB +# Problem found when testing, if there is a duplicate entry only the last one is used, +# not the first or both, another problem is that when testing I found a bug in Config::Simple, if you have a tab +# infront of your # on a comment it breaks ... +# logging = yes # Should Logging be enabled (YES,ON,1 or NO,OFF,0)(if not specified defaults to no) +# logdir = "/root/perl" # What is the base directory the logs should be stored. +# logfile = "userlist.txt" # What should the file be named. +# VERY IMPORTANT anything that has a "\" (backslash) in it ex. "C:\" MUST be changed to a double "\\" for +# it to be used in the script. ex. "C:\\" + +[global] +logging = yes +logdir = "/home/samba/netlogon" +logfile = "UserLogs.txt" +mkprofile = 1 +timesync = yes +sambaconf = "/etc/samba/smb.conf" +logtype = file + +# Change and uncomment the below value to force the servername, some clients ocassionally +# have trouble picking up the right servername so it may need to be set. It CANNOT be left blank AND uncommented. +servername = "TIGER" + +[common] +public = P:, public +home = H:, /home + +[groupmap] +adm = R:, NETLOGON, Y:, ARCHIVES +teachers = S:, RECORDS, X:, SIS +plato = T:, PLATO +webpage = W:, WEB +hsoffice = N:, HSOFFICE, Q:, COMMON, X:, SIS +suoffice = N:, super, Q:, COMMON, X:, SIS +emoffice = N:, emOFFICE, Q:, COMMON, X:, SIS +tech = O:, utils +yearbook = Y:, yearbook + +[usermap] +rnance = G:, GHOST, I:, TTL, Y:, ARCHIVES, R:, NETLOGON, X:, SIS +lwatts = G:, GHOST, I:, TTL, Y:, ARCHIVES, R:, NETLOGON, X:, SIS +droot = U:, stuhomes +2007mbk = Y:, yearbook +2008mll = Y:, yearbook +2008jtj = Y:, yearbook +2007tja = Y:, yearbook +2007hms = Y:, yearbook +2006dpv = Y:, yearbook +2006jwb2 = Y:, yearbook +2007npd = Y:, yearbook +astewart = Y:, yearbook + + + +# Here is where things get confusing, you can assign a computer, or make a group of computers. +# The same context will go for ip address's as well, however you can also specify ip ranges, +# but I have not yet figured out how to do multiple ranges. +# Use the following examples for help. +# To define a single computer to do commands +# mymachinename = command1, command2 +# To define a group of computers to do commands +# mymachinegroup = machinename1, machinename2 +# [performcommands] +# mymachinegroup = command1,command2 +# iprangegroup1 = 10.1.2.1 - 10.1.3.1 + + + +[machines] + +[ip] +sixthemints = 10.1.5.201 - 10.1.5.215 + +[performcommands] +common = "XCOPY P:\\TYPEN32.INI C:\\WINDOWS\\ /Y \>NUL", "XCOPY P:\\ARPROGRAMS\\DBLOCATION\\\*\.\* C:\\WINDOWS\\ /Y \>NUL", "XCOPY P:\\EMACTIVITIES\\EMGAMESPREFS.INI C:\\WINDOWS\\ /Y \>NUL", "PATH\=\%PATH\%;p:\\PXPerl\parrot\\bin;p:\\PXPerl\\bin" +sixthemints = "start \\\\10.1.5.20\\printer" diff --git a/examples/logon/mklogon/mklogon.pl b/examples/logon/mklogon/mklogon.pl new file mode 100644 index 0000000000..870abd192c --- /dev/null +++ b/examples/logon/mklogon/mklogon.pl @@ -0,0 +1,392 @@ +#!/usr/bin/perl -w + +# 05/01/2005 - 18:07:10 +# +# mklogon.pl - Login Script Generator +# Copyright (C) 2005 Ricky Nance +# ricky.nance@gmail.com +# http://www.weaubleau.k12.mo.us/~rnance/samba/mklogon.txt +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or 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/>. +# + +# Version: 1.0 (Stable) +# Revised: 07/28/2005 + +# Comments... +# Working on logging to the system logs, Logs user activity, but not errors yet. + +use strict; +use Getopt::Long; + +eval { require Config::Simple; }; +if ($@) { + print("\n"); + print( "It appears as though you don't have the Config Simple perl module installed.\n" ); + print("The package is typically called 'Config::Simple' \n"); + print("and it needs to be installed, before you can use this utility\n"); + print("Most PERL installations will allow you to use a command like\n"); + print("\ncpan -i Config::Simple\n"); + print("from the command line while logged in as the root user.\n"); + print("\n"); + exit(1); +} + +# use Data::Dumper; #Used for debugging purposes + +# This variable should point to the external conf file, personally I would set +# it to /etc/samba/mklogon.conf +my $configfile; + +foreach my $dir ( ( '/etc', '/etc/samba', '/usr/local/samba/lib' ) ) { + if ( -e "$dir/mklogon.conf" ) { + $configfile = "$dir/mklogon.conf"; + last; + } +} + +# This section will come directly from the samba server. Basically it just makes the script easier to read. +my $getopts = GetOptions( + 'u|username=s' => \my $user, + 'm|machine=s' => \my $machine, + 's|servername=s' => \my $server, + 'o|ostype=s' => \my $os, + 'i|ip=s' => \my $ip, + 'd|date=s' => \my $smbdate, + 'h|help|?' => \my $help +); + +if ($help) { + help(); + exit(0); +} + +# We want the program to error out if its missing an argument. +if ( !defined($user) ) { error("username"); } +if ( !defined($machine) ) { error("machine name") } +if ( !defined($server) ) { error("server name") } +if ( !defined($os) ) { error("operating system") } +if ( !defined($ip) ) { error("ip address") } +if ( !defined($smbdate) ) { error("date") } + +# This section will be read from the external config file +my $cfg = new Config::Simple($configfile) or die "Could not find $configfile"; + +# Read this part from the samba config +my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time); +my $sambaconf = $cfg->param("global.sambaconf") or die "Couldn't find your samba config! \n"; +my $smbcfg = new Config::Simple( filename => $sambaconf, syntax => "ini" ); +my $smbprof = $smbcfg->param("profiles.path"); +my $smbnetlogdir = $smbcfg->param("netlogon.path"); +my $logging = lc( $cfg->param("global.logging") ); +my $mkprofile = lc( $cfg->param("global.mkprofile") ); +my $logdir = $cfg->param("global.logdir"); +my $logfile = $cfg->param("global.logfile"); +my $logs = "$logdir\/$logfile"; +my $logtype = $cfg->param("global.logtype"); +my $usermap = "usermap.$user"; +my $osmap = "os.$os"; +my @ostype = $cfg->param($osmap); +my @username = $cfg->param($usermap); +my $compname = $cfg->param( -block => "machines" ); +my $ipname = $cfg->param( -block => "ip" ); +my $timesync = $cfg->param("global.timesync"); +my $altserver = $cfg->param("global.servername"); +if ( defined($altserver) ) { $server = $altserver; } +$server = uc($server); + +# Lets start logging stuff if it is turned on in the config +if ( $logging =~ m/on|yes|1/i ) { + if ($logtype =~ m/file/i) { + print "----- Logging is turned on in the config. -----\n"; + print "----- Location of the logfile is \"$logs\" -----\n"; + open LOG, ">>$logs"; + printf LOG "Date: $smbdate Time: "; + printf LOG '%02d', $hour; + print LOG ":"; + printf LOG '%02d', $min; + print LOG "."; + printf LOG '%02d', $sec; + print LOG " -- User: $user - Machine: $machine - IP: $ip -- \n"; + close(LOG); + } elsif ($logtype =~ m/syslog|system/i){ + use Sys::Syslog; + my $alert = "User: $user Logged into $machine ($ip) at $hour:$min.$sec on $smbdate."; + openlog($0, 'cons', 'user'); + syslog('alert', $alert); + closelog(); + + } +} else { + print "----- Logging is turned off in the config. -----\n"; +} + +# If the user wants to make profiles with this script lets go +if ( defined($smbprof) ) { + if ( $mkprofile =~ m/on|yes|1/i ) { + print "----- Automatic making of user profiles is turned on in the config. ----- \n"; + ( my $login, my $pass, my $uid, my $gid ) = getpwnam($user) + or die "$user not in passwd file \n"; + $smbprof =~ s/\%U/$user/g; + my $dir2 = "$smbprof\/$user"; + print "$smbprof \n"; + print "$dir2 \n"; + if ( !-e $dir2 ) { + print "Creating " . $user . "'s profile with a uid of $uid\n"; + mkdir $smbprof; + mkdir $dir2; + chomp($user); +# chown $uid, $gid, $smbprof; + chown $uid, $gid, $dir2; + } else { + print $user . "'s profile already exists \n"; + } + } else { + print "----- Automatic making of user profiles is turned off in the config. ----- \n"; + } +} + +# Lets start making the batch files. +open LOGON, ">$smbnetlogdir\/$user.bat" or die "Unable to create userfile $smbnetlogdir\/$user.bat"; +print LOGON "\@ECHO OFF \r\n"; + +if ( $timesync =~ m/on|yes|1/i ) { + print LOGON "NET TIME /SET /YES \\\\$server \r\n"; +} else { + print "----- Time syncing to the client is turned off in the config. -----\n"; +} + +# Mapping from the common section +my $common = $cfg->param( -block => "common" ); +for my $key ( keys %$common ) { + drive_map( @{ $common->{$key} } ); +} + +my @perform_common = $cfg->param("performcommands.common"); +if ( defined( $perform_common[0] ) ) { + foreach (@perform_common) { + print LOGON "$_ \r\n"; + } +} + +# Map shares on a per user basis. +drive_map(@username); + +# Map shares based on the Operating System. +drive_map(@ostype); + +# Map shares only if they are in a group +# This line checks against the unix "groups" command, to see the secondary groups of a user. +my @usergroups = split( /\s/, do { open my $groups, "-|", groups => $user; <$groups> } ); +foreach (@usergroups) { + my $groupmap = "groupmap.$_"; + my @groupname = $cfg->param($groupmap); + drive_map(@groupname); +} + +#Here is where we check the machine name against the config... +for my $key ( keys %$compname ) { + my $test = $compname->{$key}; + if ( ref $test eq 'ARRAY' ) { + foreach (@$test) { + if ( $_ eq $machine ) { + my $performit = $cfg->param("performcommands.$key"); + if ( defined($performit) ) { + if ( ref $performit ) { + foreach (@$performit) { print LOGON "$_ \r\n"; } + } else { + print LOGON "$performit \r\n"; + } + } + } + } + } + elsif ( $test eq $machine ) { + my $performit = $cfg->param("performcommands.$key"); + if ( defined($performit) ) { + if ( ref $performit ) { + foreach (@$performit) { print LOGON "$_ \r\n"; } + } else { + print LOGON "$performit \r\n"; + } + } + } +} + +# Here is where we test the ip address against the client to see if they have "Special Mapping" +# A huge portion of the ip matching code was made by +# Carsten Schaub (rcsu in the #samba chan on freenode.net) + +my $val; +for my $key ( sort keys %$ipname ) { + if ( ref $ipname->{$key} eq 'ARRAY' ) { + foreach ( @{ $ipname->{$key} } ) { + getipval( $_, $key ); + } + } else { + getipval( $ipname->{$key}, $key ); + } +} + +sub getipval { + my ( $range, $rangename ) = @_; + if ( parse( $ip, ipmap($range) ) ) { + if ( $val eq 'true' ) { + my $performit = $cfg->param("performcommands.$rangename"); + if ( defined($performit) ) { + if ( ref $performit ) { + foreach (@$performit) { print LOGON "$_ \r\n"; } + } else { + print LOGON "$performit \r\n"; + } + } + } elsif ( $val eq 'false' ) { + } + } else { + } +} + +sub ipmap { + my $pattern = shift; + my ( $iprange, $iprange2, $ipmask ); + if ( $pattern =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2})$/ ) { + # 1.1.1.1/3 notation + $iprange = pack( "U4", $1, $2, $3, $4 ); + $ipmask = pack( "U4", 0, 0, 0, 0 ); + my $numbits = $5; + for ( my $i = 0 ; $i < $numbits ; $i++ ) { + vec( $ipmask, int( $i / 8 ) * 8 + ( 8 - ( $i % 8 ) ) - 1, 1 ) = 1; + } + $iprange &= "$ipmask"; + } elsif ( $pattern =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/ ) { + # 1.1.1.1/255.255.255.255 notation + $iprange = pack( "U4", $1, $2, $3, $4 ); + $ipmask = pack( "U4", $5, $6, $7, $8 ); + $iprange &= "$ipmask"; + } elsif ( $pattern =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ ) { + # 1.1.1.1 notation + $iprange = pack( "U4", $1, $2, $3, $4 ); + $ipmask = pack( "U4", 255, 255, 255, 255 ); + } elsif ( $pattern =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\s*\-\s*(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ ) { + # 1.1.1.1 - 2.2.2.2 notation + $iprange = pack( "U4", $1, $2, $3, $4 ); + $iprange2 = pack( "U4", $5, $6, $7, $8 ); + $ipmask = pack( "U4", 255, 255, 255, 255 ); + } else { + return; + } + return $iprange, $ipmask, $iprange2; +} + +sub parse { + my ( $origip, $ipbase, $ipmask, $iprange2 ) = @_; + $origip =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; + $origip = pack( "U4", $1, $2, $3, $4 ); + if ( defined($iprange2) ) { + if ( $ipbase le $origip && $origip le $iprange2 ) { + return $val = 'true'; + } else { + return $val = 'false'; + } + } elsif ( ( "$origip" & "$ipmask" ) eq $ipbase ) { + return $val = 'true'; + } else { + return $val = 'false'; + } +} + +# This sub will distinguish the drive mappings +sub drive_map { + my @data = @_; + for ( my $i = 0 ; $i < scalar(@data) ; ) { + if ( $data[$i] =~ m/^[a-z]\:$/i ) { + my $driveletter = $data[$i]; + $i++; + my $sharename = $data[$i]; + $i++; + if ( $sharename eq '/home' ) { + print LOGON uc("NET USE $driveletter \\\\$server\\$user \/Y \r\n"); + } else { + print LOGON + uc("NET USE $driveletter \\\\$server\\$sharename \/Y \r\n"); + } + } else { + print LOGON uc("$data[$i] \r\n"); + $i++; + } + } +} + +close(LOGON); + +sub error { + my $var = shift(@_); + help(); + print "\n\tCritical!!! \n\n\tNo $var specified\n\n\tYou must specify a $var.\n\n"; + exit(0); +} + +sub help { + + print << "EOF" ; + + Usage: $0 [options] + + Options: + + -h,--help This help screen. + + -u,--username The name of the user from the samba server. + + -m,--machinename The name of the client connecting to the server. + + -s,--server The name of the server this script is running in. + + -o,--os The clients OS -- Windows 95/98/ME (Win95), Windows NT (WinNT), + Windows 2000 (Win2K), Windows XP (WinXP), and Windows 2003 + (Win2K3). Anything else will be known as ``UNKNOWN'' + That snippet is directly from man smb.conf. + + -i,--ip The clients IP address. + + -d,--date Time and Date returned from the samba server. + + + + --IMPORTANT-- + + + All options MUST be specified. + + The mklogon.conf file MUST be located in /etc, /etc/samba, or + /usr/local/samba/lib. + + To use this file from the command line: + $0 -u User -m machine -s servername -o ostype -i X.X.X.X -d MM/DD/YY + + To use this file from the samba server add these lines to your /etc/samba/smb.conf: + + + This line goes in the [global] section + login script = %U.bat + + This line should be at the end of the [netlogon] section. + root preexec = /path/to/mklogon.pl -u %U -m %m -s %L -o %a -i %I -d %t + + +EOF + + print "\n\n"; + +} diff --git a/examples/logon/ntlogon/README b/examples/logon/ntlogon/README new file mode 100644 index 0000000000..e33c565d71 --- /dev/null +++ b/examples/logon/ntlogon/README @@ -0,0 +1,160 @@ +ntlogon.py v0.8b Copyright 2002 by Timothy (rhacer) Grant +This programme is released under the terms of the GNU Public License +This programme has NO WARRANTY of any kind, use at your own risk. + +=================== +CHANGES SINCE v0.7b +=================== +included patch that made machine name %m a macro substitution value. +Thanks to: Nick Lopez <kimo_sabe@atdot.org> + +================== +CHANGES SINCE v0.6 +================== +PLEASE NOT THAT I AM CONSIDERING THIS A BETA UNTIL I GET SOME FEEDBACK +FROM USERS ON WHETHER THE MACRO FEATURE WORKS FOR THEM. + +added the ability to define substitution macros: see the useage section + +removed the large docstring from the file and moved the information to +the USEAGE section of this file + +cleaned up the code and made more flexible + +improved the code comments + +================== +CHANGES SINCE v0.5 +================== +added a -v --version switch + +added a --pause switch which will put a pause statement between each +non-blank line of the script. + +=============== +A PERSONAL NOTE +=============== +When I originally posted v0.5 on Freshmeat, I really expected *some* +feedback. To date this little script has been downloaded over 700 times, but +absolutely nobody has sent me an e-mail to tell me if it is useful, or if +it is absolutely the stupidest waste of bandwidth they have ever seen. +I'd really love to know if even one person other than me and the other techs +here at Avalon have found it useful. + +Thanks. + rhacer (rhacer@craigelachie.org) + +September 27, 2000 +Thanks to those that did respond to my plea! I'd still love to hear from +any other users! + +============ +INTRODUCTION +============ +As my experience with Linux and Samba increased, I had no trouble whipping up +a custom Perl, Python or Bash script to create Samba Logon Scripts, but I +noticed that I changed things from place to place, and that my users had *no* +chance of ever figuring out how to modify those scripts themselves. + +In an attempt to create a company wide standard that both my co-workers and my +customers could *easily* modify I hit upon the scheme I used here. + +I settled on an INI file feel, because most who have experience with Win boxes +have some concept of INI files. + +============ +INSTALLATION +============ +The distribution archive contains three files: + +README This file +ntlogon.py The actual Python script (place in /usr/local/samba/bin) +ntlogon.conf A sample configuration file (place in /etc) + +This script was created using Python v1.5.2, and I believe it uses only +standard libraries. + +Your smb.conf file needs to contain a netlogon section similar to the +following (These settings *are not* normal on a RH box. These settings +are all based on the excellent book that I learned Samba from: Samba +Integrating Unix and Windows by John D. Blair. It is somewhat out of +date now, but that's the history of the strange file locations): + +[netlogon] + path = /usr/local/samba/netlogon + writeable = no + guest ok = no + root preexec = /usr/local/samba/bin/ntlogon --user=%U --os=%m + root postexec = rm /usr/local/samba/netlogon/%U.bat + +====== +USEAGE +====== +PLEASE SEE NTLOGON.CONF FOR A DETAILED CONFIGURATION EXAMPLE + +This programme will build a Windows NT logon script for users connecting +to a Samba server. Samba macros that are curently understood: + + %U user name + %G group name + %a machine architecture + %m machine netbios name + +This programme reads a configuration that looks strikingly similar to both +the Samba configuration file, and a DOS "boot menu" AUTOEXEC.BAT file. + +The default file name is /etc/ntlogon.conf (though I really think it ought +to be called ntlogon.batch!) You may change the filename by using the -f +or --templatefile startup option. + +The default netlogon directory is /usr/local/samba/netlogon though this +can be changed with the -d or --dir startup option. + +The default batch file name generated is username.bat if no username is +specified the default value is logon.bat (e.g., if --user=fred is specified +on the command line then the logon script generated will be stored in +fred.bat) + +Use the --debug option to print the logon script to screen instead of the +output file + +Use the --pause option to place a pause statement between each line of the +script to assist in debugging a logon script. + +The file is divided into sections that have headers in square brackets + +[Global] +[User-username] +[Group-groupname] +[OS-osname] + +The file may also contain user defined substitution macros. They are +defined by placing the macro name on the left side of an equal sign, +and the substitution text on the right side of the equal sign. They +are also case sensitive: + +MAINDRIVE = G: +USERDRIVE = U: +SERVERNAME = myservername + +They are referenced by prepending a "%" sign to the variable name: + +NET USE %MAINDRIVE \\\\servername\\mainshare /YES +NET USE %USERDRIVE \\\\%SERVERNAME\\usershare /YES + +============== +SPECIAL THANKS +============== +Nick Lopez <kimo_sabe@atdot.org> for the net bios name patch. + +=================== +CONTACT INFORMATION +=================== +Author : Timothy (rhacer) Grant + +I can be reached at tjg@craigelachie.org +ntlogon website www.craigelachie.org/rhacer/ntlogon + +Please feel free to contact me with any suggestions, improvements, bugs you +might find. + diff --git a/examples/logon/ntlogon/ntlogon.conf b/examples/logon/ntlogon/ntlogon.conf new file mode 100644 index 0000000000..e1573a6118 --- /dev/null +++ b/examples/logon/ntlogon/ntlogon.conf @@ -0,0 +1,44 @@ +# Everything in the Global section applies to all users logging on to the +# network +[Global] + +#Some substitution macro definitions +MAINDRIVE = G: +USERDRIVE = U: +SERVERNAME = myservername + +@ECHO "Welcome to our network!!!" +NET TIME \\servername /SET /YES +NET USE %MAINDRIVE \\%SERVERNAME\globalshare /YES + +# Map the private user area in the global section so we don't have to +# create individual user entries for each user! +NET USE %USERDRIVE \\servername\%U /YES + +# Group entries, User entries and OS entries each start with the +# keyword followed by a dash followed by--appropriately enough the Group +# name, the User name, or the OS name. +[Group-admin] +@ECHO "Welcome administrators!" +NET USE G: \\servername\adminshare1 /YES +NET USE I: \\servername\adminshare2 /YES + +[Group-peons] +@ECHO "Be grateful we let you use computers!" +NET USE G: \\servername\peonshare1 /YES + +[Group-hackers] +@ECHO "What can I do for you today great one?" +NET USE G: \\servername\hackershare1 /YES +NET USE I: \\servername\adminshare2 /YES + +[User-fred] +@ECHO "Hello there Fred!" +NET USE F: \\servername\fredsspecialshare /YES + +[OS-WfWg] +@ECHO "Time to upgrade isn't it?" + +# End configuration file + +X = Will this break? diff --git a/examples/logon/ntlogon/ntlogon.py b/examples/logon/ntlogon/ntlogon.py new file mode 100755 index 0000000000..ba46ba8ffc --- /dev/null +++ b/examples/logon/ntlogon/ntlogon.py @@ -0,0 +1,376 @@ +#!/usr/bin/env python +""" +ntlogon.py written by Timothy (rhacer) Grant + +Copyright 1999 - 2002 by Timothy Grant + +is distributed under the terms of the GNU Public License. + +The format for the configuration file is as follows: + +While there is some room for confusion, we attempt to process things in +order of specificity: Global first, Group second, User third, OS Type +forth. This order can be debated forever, but it seems to make the most +sense. + +# Everything in the Global section applies to all users logging on to the +# network +[Global] +@ECHO "Welcome to our network!!!" +NET TIME \\\\servername /SET /YES +NET USE F: \\\\servername\\globalshare /YES + +# Map the private user area in the global section so we don't have to +# create individual user entries for each user! +NET USE U: \\\\servername\\%U /YES + +# Group entries, User entries and OS entries each start with the +# keyword followed by a dash followed by--appropriately enough the Group +# name, the User name, or the OS name. +[Group-admin] +@ECHO "Welcome administrators!" +NET USE G: \\\\servername\\adminshare1 /YES +NET USE I: \\\\servername\\adminshare2 /YES + +[Group-peons] +@ECHO "Be grateful we let you use computers!" +NET USE G: \\\\servername\\peonshare1 /YES + +[Group-hackers] +@ECHO "What can I do for you today great one?" +NET USE G: \\\\servername\\hackershare1 /YES +NET USE I: \\\\servername\\adminshare2 /YES + +[User-fred] +@ECHO "Hello there Fred!" +NET USE F: \\\\servername\\fredsspecialshare /YES + +[OS-WfWg] +@ECHO "Time to upgrade it?" + +# End configuration file + +usage: ntlogon [-g | --group=groupname] + [-u | --user=username] + [-o | --os=osname] + [-m | --machine=netbiosname] + [-f | --templatefile=filename] + [-d | --dir=netlogon directory] + [-v | --version] + [-h | --help] + [--pause] + [--debug] +""" +# +#" This quote mark is an artifact of the inability of my editor to +# correctly colour code anything after the triple-quoted docstring. +# if your editor does not have this flaw, feel free to remove it. + + +import sys +import getopt +import re +import string +import os + +version = "ntlogon.py v0.8" + +def buildScript(buf, sections, group, user, ostype, machine, debug, pause): + """ + buildScript() Takes the contents of the template file and builds + a DOS batch file to be executed as an NT logon script. It does this + by determining which sections of the configuration file should be included + and creating a list object that contains each line contained in each + included section. The list object is then returned to the calling + routine. + + All comments (#) are removed. A REM is inserted to show + which section of the configuration file each line comes from. + We leave blanklines as they are sometimes useful for debugging + + We also replace all of the Samba macros (e.g., %U, %G, %a, %m) with their + expanded versions which have been passed to us by smbd + """ + hdrstring = '' + script = [] + + # + # These are the Samba macros that we currently know about. + # any user defined macros will also be added to this dictionary. + # We do not store the % sign as part of the macro name. + # The replace routine will prepend the % sign to all possible + # replacements. + # + macros = { + 'U': user, + 'G': group, + 'a': ostype, + 'm': machine + } + + # + # Process each section defined in the list sections + # + for s in sections: + # print 'searching for: ' + s + + idx = 0 + + while idx < len(buf): + ln = buf[idx] + + # + # We need to set up a regex for each possible section we + # know about. This is slightly complicated due to the fact + # that section headers contain user defined text. + # + if s == 'Global': + hdrstring = '\[ *' + s + ' *\]' + elif s == 'Group': + hdrstring = '\[ *' + s + ' *- *' + group + ' *\]' + elif s == 'User': + hdrstring = '\[ *' + s + ' *- *' + user + ' *\]' + elif s == 'OS': + hdrstring = '\[ *' + s + ' *- *' + ostype + ' *\]' + elif s == 'Machine': + hdrstring = '\[ *' + s + ' *- *' + machine + ' *\]' + + # + # See if we have found a section header + # + if re.search(r'(?i)' + hdrstring, ln): + idx = idx + 1 # increment the counter to move to the next + # line. + + x = re.match(r'([^#\r\n]*)', ln) # Determine the section + # name and strip out CR/LF + # and comment information + + if debug: + print 'rem ' + x.group(1) + ' commands' + else: + # create the rem at the beginning of each section of the + # logon script. + script.append('rem ' + x.group(1) + ' commands') + + # + # process each line until we have found another section + # header + # + while not re.search(r'.*\[.*\].*', buf[idx]): + + # + # strip comments and line endings + # + x = re.match(r'([^#\r\n]*)', buf[idx]) + + if string.strip(x.group(1)) != '' : + # if there is still content after stripping comments and + # line endings then this is a line to process + + line = x.group(1) + + # + # Check to see if this is a macro definition line + # + vardef = re.match(r'(.*)=(.*)', line) + + if vardef: + varname = string.strip(vardef.group(1)) # Strip leading and + varsub = string.strip(vardef.group(2)) # and trailing spaces + + if varname == '': + print "Error: No substition name specified line: %d" % idx + sys.exit(1) + + if varsub == '': + print "Error: No substitution text provided line: %d" % idx + sys.exit(1) + + if macros.has_key(varname): + print "Warning: macro %s redefined line: %d" % (varname, idx) + + macros[varname] = varsub + idx = idx + 1 + continue + + # + # Replace all the macros that we currently + # know about. + # + # Iterate over the dictionary that contains all known + # macro substitutions. + # + # We test for a macro name by prepending % to each dictionary + # key. + # + for varname in macros.keys(): + line = re.sub(r'%' + varname + r'(\W)', + macros[varname] + r'\1', line) + + if debug: + print line + if pause: + print 'pause' + else: + script.append(line) + + idx = idx + 1 + + if idx == len(buf): + break # if we have reached the end of the file + # stop processing. + + idx = idx + 1 # increment the line counter + + if debug: + print '' + else: + script.append('') + + return script + +# End buildScript() + +def run(): + """ + run() everything starts here. The main routine reads the command line + arguments, opens and reads the configuration file. + """ + configfile = '/etc/ntlogon.conf' # Default configuration file + group = '' # Default group + user = '' # Default user + ostype = '' # Default os + machine = '' # Default machine type + outfile = 'logon.bat' # Default batch file name + # this file name WILL take on the form + # username.bat if a username is specified + debug = 0 # Default debugging mode + pause = 0 # Default pause mode + outdir = '/usr/local/samba/netlogon/' # Default netlogon directory + + sections = ['Global', 'Machine', 'OS', 'Group', 'User'] # Currently supported + # configuration file + # sections + + options, args = getopt.getopt(sys.argv[1:], 'd:f:g:ho:u:m:v', + ['templatefile=', + 'group=', + 'help', + 'os=', + 'user=', + 'machine=', + 'dir=', + 'version', + 'pause', + 'debug']) + + # + # Process the command line arguments + # + for i in options: + # template file to process + if (i[0] == '-f') or (i[0] == '--templatefile'): + configfile = i[1] + # print 'configfile = ' + configfile + + # define the group to be used + elif (i[0] == '-g') or (i[0] == '--group'): + group = i[1] + # print 'group = ' + group + + # define the os type + elif (i[0] == '-o') or (i[0] == '--os'): + ostype = i[1] + # print 'os = ' + os + + # define the user + elif (i[0] == '-u') or (i[0] == '--user'): + user = i[1] + outfile = user + '.bat' # Setup the output file name + # print 'user = ' + user + + # define the machine + elif (i[0] == '-m') or (i[0] == '--machine'): + machine = i[1] + + # define the netlogon directory + elif (i[0] == '-d') or (i[0] == '--dir'): + outdir = i[1] + # print 'outdir = ' + outdir + + # if we are asked to turn on debug info, do so. + elif (i[0] == '--debug'): + debug = 1 + # print 'debug = ' + debug + + # if we are asked to turn on the automatic pause functionality, do so + elif (i[0] == '--pause'): + pause = 1 + # print 'pause = ' + pause + + # if we are asked for the version number, print it. + elif (i[0] == '-v') or (i[0] == '--version'): + print version + sys.exit(0) + + # if we are asked for help print the docstring. + elif (i[0] == '-h') or (i[0] == '--help'): + print __doc__ + sys.exit(0) + + # + # open the configuration file + # + try: + iFile = open(configfile, 'r') + except IOError: + print 'Unable to open configuration file: ' + configfile + sys.exit(1) + + + # + # open the output file + # + if not debug: + try: + oFile = open(outdir + outfile, 'w') + except IOError: + print 'Unable to open logon script file: ' + outdir + outfile + sys.exit(1) + + buf = iFile.readlines() # read in the entire configuration file + + # + # call the script building routine + # + script = buildScript(buf, sections, group, user, ostype, machine, debug, pause) + + # + # write out the script file + # + if not debug: + for ln in script: + oFile.write(ln + '\r\n') + if pause: + if string.strip(ln) != '': # Because whitespace + oFile.write('pause' + '\r\n') # is a useful tool, we + # don't put pauses after + # an empty line. + + +# End run() + +# +# immediate-mode commands, for drag-and-drop or execfile() execution +# +if __name__ == '__main__': + run() +else: + print "Module ntlogon.py imported." + print "To run, type: ntlogon.run()" + print "To reload after changes to the source, type: reload(ntlogon)" + +# +# End NTLogon.py +# diff --git a/examples/misc/adssearch.pl b/examples/misc/adssearch.pl new file mode 100755 index 0000000000..d17e680ec8 --- /dev/null +++ b/examples/misc/adssearch.pl @@ -0,0 +1,1878 @@ +#!/usr/bin/perl -w +# +# adssearch.pl - query an Active Directory server and +# display objects in a human readable format +# +# Copyright (C) Guenther Deschner <gd@samba.org> 2003-2008 +# +# TODO: add range retrieval +# write sddl-converter, decode userParameters +# apparently only win2k3 allows simple-binds with machine-accounts. +# make sasl support independent from Authen::SASL::Cyrus v >0.11 +use strict; + +use Net::LDAP; +use Net::LDAP::Control; +use Net::LDAP::Constant qw(LDAP_REFERRAL); +use Convert::ASN1; +use Time::Local; +use POSIX qw(strftime); +use Getopt::Long; + +my $have_sasl; +my $works_sasl; +my $pref_version; +BEGIN { + my $class = 'Authen::SASL'; + $pref_version = "0.32"; + if ( eval "require $class;" ) { + $have_sasl = 1; + } + if ( eval "Net::LDAP->VERSION($pref_version);" ) { + $works_sasl = 1; + } +} + +# users may set defaults here +my $base = ""; +my $binddn = ""; +my $password = ""; +my $server = ""; +my $rebind_url; + + +my $tdbdump = "/usr/bin/tdbdump"; +my $testparm = "/usr/bin/testparm"; +my $net = "/usr/bin/net"; +my $dig = "/usr/bin/dig"; +my $nmblookup = "/usr/bin/nmblookup"; +my $secrets_tdb = "/etc/samba/secrets.tdb"; +my $klist = "/usr/bin/klist"; +my $kinit = "/usr/bin/kinit"; +my $workgroup = ""; +my $machine = ""; +my $realm = ""; + +# parse input +my ( + $opt_asq, + $opt_base, + $opt_binddn, + $opt_debug, + $opt_display_extendeddn, + $opt_display_metadata, + $opt_display_raw, + $opt_domain_scope, + $opt_dump_rootdse, + $opt_dump_schema, + $opt_dump_wknguid, + $opt_fastbind, + $opt_help, + $opt_host, + $opt_machine, + $opt_notify, + $opt_notify_nodiffs, + $opt_paging, + $opt_password, + $opt_port, + $opt_realm, + $opt_saslmech, + $opt_search_opt, + $opt_scope, + $opt_simpleauth, + $opt_starttls, + $opt_user, + $opt_verbose, + $opt_workgroup, +); + +GetOptions( + 'asq=s' => \$opt_asq, + 'base|b=s' => \$opt_base, + 'D|DN=s' => \$opt_binddn, + 'debug=i' => \$opt_debug, + 'domain_scope' => \$opt_domain_scope, + 'extendeddn|e:i' => \$opt_display_extendeddn, + 'fastbind' => \$opt_fastbind, + 'help' => \$opt_help, + 'host|h=s' => \$opt_host, + 'machine|P' => \$opt_machine, + 'metadata|m' => \$opt_display_metadata, + 'nodiffs' => \$opt_notify_nodiffs, + 'notify|n' => \$opt_notify, + 'paging:i' => \$opt_paging, + 'password|w=s' => \$opt_password, + 'port=i' => \$opt_port, + 'rawdisplay' => \$opt_display_raw, + 'realm|R=s' => \$opt_realm, + 'rootDSE' => \$opt_dump_rootdse, + 'saslmech|Y=s' => \$opt_saslmech, + 'schema|c' => \$opt_dump_schema, + 'scope|s=s' => \$opt_scope, + 'searchopt:i' => \$opt_search_opt, + 'simpleauth|x' => \$opt_simpleauth, + 'tls|Z' => \$opt_starttls, + 'user|U=s' => \$opt_user, + 'verbose|v' => \$opt_verbose, + 'wknguid' => \$opt_dump_wknguid, + 'workgroup|k=s' => \$opt_workgroup, + ); + + +if (!@ARGV && !$opt_dump_schema && !$opt_dump_rootdse && !$opt_notify || $opt_help) { + usage(); + exit 1; +} + +if ($opt_fastbind && !$opt_simpleauth) { + printf("LDAP fast bind can only be performed with simple binds\n"); + exit 1; +} + +if ($opt_notify) { + $opt_paging = undef; +} + +# get the query +my $query = shift; +my @attrs = @ARGV; + +# some global vars +my $filter = ""; +my ($dse, $uri); +my ($attr, $value); +my (@ctrls, @ctrls_s); +my ($ctl_paged, $cookie); +my ($page_count, $total_entry_count); +my ($sasl_hd, $async_ldap_hd, $sync_ldap_hd); +my ($mesg, $usn); +my (%entry_store); +my $async_search; + +# fixed values and vars +my $set = "X"; +my $unset = "-"; +my $tabsize = "\t\t\t"; + +# get defaults +my $scope = $opt_scope || "sub"; +my $port = $opt_port; + +my %ads_controls = ( +"LDAP_SERVER_NOTIFICATION_OID" => "1.2.840.113556.1.4.528", +"LDAP_SERVER_EXTENDED_DN_OID" => "1.2.840.113556.1.4.529", +"LDAP_PAGED_RESULT_OID_STRING" => "1.2.840.113556.1.4.319", +"LDAP_SERVER_SD_FLAGS_OID" => "1.2.840.113556.1.4.801", +"LDAP_SERVER_SORT_OID" => "1.2.840.113556.1.4.473", +"LDAP_SERVER_RESP_SORT_OID" => "1.2.840.113556.1.4.474", +"LDAP_CONTROL_VLVREQUEST" => "2.16.840.1.113730.3.4.9", +"LDAP_CONTROL_VLVRESPONSE" => "2.16.840.1.113730.3.4.10", +"LDAP_SERVER_RANGE_RETRIEVAL" => "1.2.840.113556.1.4.802", #unsure +"LDAP_SERVER_SHOW_DELETED_OID" => "1.2.840.113556.1.4.417", +"LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID" => "1.2.840.113556.1.4.521", +"LDAP_SERVER_LAZY_COMMIT_OID" => "1.2.840.113556.1.4.619", +"LDAP_SERVER_TREE_DELETE_OID" => "1.2.840.113556.1.4.805", +"LDAP_SERVER_DIRSYNC_OID" => "1.2.840.113556.1.4.841", +"LDAP_SERVER_VERIFY_NAME_OID" => "1.2.840.113556.1.4.1338", +"LDAP_SERVER_DOMAIN_SCOPE_OID" => "1.2.840.113556.1.4.1339", +"LDAP_SERVER_SEARCH_OPTIONS_OID" => "1.2.840.113556.1.4.1340", +"LDAP_SERVER_PERMISSIVE_MODIFY_OID" => "1.2.840.113556.1.4.1413", +"LDAP_SERVER_ASQ_OID" => "1.2.840.113556.1.4.1504", +"NONE (Get stats control)" => "1.2.840.113556.1.4.970", +"LDAP_SERVER_QUOTA_CONTROL_OID" => "1.2.840.113556.1.4.1852", +"LDAP_SERVER_SHUTDOWN_NOTIFY_OID" => "1.2.840.113556.1.4.1907", +); + +my %ads_capabilities = ( +"LDAP_CAP_ACTIVE_DIRECTORY_OID" => "1.2.840.113556.1.4.800", +"LDAP_CAP_ACTIVE_DIRECTORY_V51_OID" => "1.2.840.113556.1.4.1670", +"LDAP_CAP_ACTIVE_DIRECTORY_LDAP_INTEG_OID" => "1.2.840.113556.1.4.1791", +); + +my %ads_extensions = ( +"LDAP_START_TLS_OID" => "1.3.6.1.4.1.1466.20037", +"LDAP_TTL_EXTENDED_OP_OID" => "1.3.6.1.4.1.1466.101.119.1", +"LDAP_SERVER_FAST_BIND_OID" => "1.2.840.113556.1.4.1781", +"NONE (TTL refresh extended op)" => "1.3.6.1.4.1.1466.101.119.1", +); + +my %ads_matching_rules = ( +"LDAP_MATCHING_RULE_BIT_AND" => "1.2.840.113556.1.4.803", +"LDAP_MATCHING_RULE_BIT_OR" => "1.2.840.113556.1.4.804", +); + +my %wknguids = ( +"WELL_KNOWN_GUID_COMPUTERS" => "AA312825768811D1ADED00C04FD8D5CD", +"WELL_KNOWN_GUID_DOMAIN_CONTROLLERS" => "A361B2FFFFD211D1AA4B00C04FD7D83A", +"WELL_KNOWN_GUID_SYSTEM" => "AB1D30F3768811D1ADED00C04FD8D5CD", +"WELL_KNOWN_GUID_USERS" => "A9D1CA15768811D1ADED00C04FD8D5CD", +); + +my %ads_systemflags = ( +"FLAG_DONT_REPLICATE" => 0x00000001, # 1 +"FLAG_REPLICATE_TO_GC" => 0x00000002, # 2 +"FLAG_ATTRIBUTE_CONSTRUCT" => 0x00000004, # 4 +"FLAG_CATEGORY_1_OBJECT" => 0x00000010, # 16 +"FLAG_DELETE_WITHOUT_TOMBSTONE" => 0x02000000, # 33554432 +"FLAG_DOMAIN_DISALLOW_MOVE" => 0x04000000, # 67108864 +"FLAG_DOMAIN_DISALLOW_RENAME" => 0x08000000, # 134217728 +#"FLAG_CONFIG_CAN_MOVE_RESTRICTED" => 0x10000000, # 268435456 # only setable on creation +#"FLAG_CONFIG_CAN_MOVE" => 0x20000000, # 536870912 # only setable on creation +#"FLAG_CONFIG_CAN_RENAME" => 0x40000000, # 1073741824 # only setable on creation +"FLAG_DISALLOW_DELETE" => 0x80000000, # 2147483648 +); + +my %ads_mixed_domain = ( +"NATIVE_LEVEL_DOMAIN" => 0, +"MIXED_LEVEL_DOMAIN" => 1, +); + +my %ads_ds_func = ( +"DS_BEHAVIOR_WIN2000" => 0, # untested +"DS_BEHAVIOR_WIN2003" => 2, +"DS_BEHAVIOR_WIN2008" => 3, +); + +my %ads_instance_type = ( +"DS_INSTANCETYPE_IS_NC_HEAD" => 0x1, +"IT_WRITE" => 0x4, +"IT_NC_ABOVE" => 0x8, +); + +my %ads_uacc = ( + "ACCOUNT_NEVER_EXPIRES" => 0x000000, # 0 + "ACCOUNT_OK" => 0x800000, # 8388608 + "ACCOUNT_LOCKED_OUT" => 0x800010, # 8388624 +); + +my %ads_enctypes = ( + "DES-CBC-CRC" => 0x01, + "DES-CBC-MD5" => 0x02, + "RC4_HMAC_MD5" => 0x04, + "AES128_CTS_HMAC_SHA1_96" => 0x08, + "AES128_CTS_HMAC_SHA1_128" => 0x10, +); + +my %ads_gpoptions = ( + "GPOPTIONS_INHERIT" => 0, + "GPOPTIONS_BLOCK_INHERITANCE" => 1, +); + +my %ads_gplink_opts = ( + "GPLINK_OPT_NONE" => 0, + "GPLINK_OPT_DISABLED" => 1, + "GPLINK_OPT_ENFORCED" => 2, +); + +my %ads_gpflags = ( + "GPFLAGS_ALL_ENABLED" => 0, + "GPFLAGS_USER_SETTINGS_DISABLED" => 1, + "GPFLAGS_MACHINE_SETTINGS_DISABLED" => 2, + "GPFLAGS_ALL_DISABLED" => 3, +); + +my %ads_serverstate = ( + "SERVER_ENABLED" => 1, + "SERVER_DISABLED" => 2, +); + +my %ads_sdeffective = ( + "OWNER_SECURITY_INFORMATION" => 0x01, + "DACL_SECURITY_INFORMATION" => 0x04, + "SACL_SECURITY_INFORMATION" => 0x10, +); + +my %ads_trustattrs = ( + "TRUST_ATTRIBUTE_NON_TRANSITIVE" => 1, + "TRUST_ATTRIBUTE_TREE_PARENT" => 2, + "TRUST_ATTRIBUTE_TREE_ROOT" => 3, + "TRUST_ATTRIBUTE_UPLEVEL_ONLY" => 4, +); + +my %ads_trustdirection = ( + "TRUST_DIRECTION_INBOUND" => 1, + "TRUST_DIRECTION_OUTBOUND" => 2, + "TRUST_DIRECTION_BIDIRECTIONAL" => 3, +); + +my %ads_trusttype = ( + "TRUST_TYPE_DOWNLEVEL" => 1, + "TRUST_TYPE_UPLEVEL" => 2, + "TRUST_TYPE_KERBEROS" => 3, + "TRUST_TYPE_DCE" => 4, +); + +my %ads_pwdproperties = ( + "DOMAIN_PASSWORD_COMPLEX" => 1, + "DOMAIN_PASSWORD_NO_ANON_CHANGE" => 2, + "DOMAIN_PASSWORD_NO_CLEAR_CHANGE" => 4, + "DOMAIN_LOCKOUT_ADMINS" => 8, + "DOMAIN_PASSWORD_STORE_CLEARTEXT" => 16, + "DOMAIN_REFUSE_PASSWORD_CHANGE" => 32, +); + +my %ads_uascompat = ( + "LANMAN_USER_ACCOUNT_SYSTEM_NOLIMITS" => 0, + "LANMAN_USER_ACCOUNT_SYSTEM_COMPAT" => 1, +); + +my %ads_frstypes = ( + "REPLICA_SET_SYSVOL" => 2, # unsure + "REPLICA_SET_DFS" => 1, # unsure + "REPLICA_SET_OTHER" => 0, # unsure +); + +my %ads_gp_cse_extensions = ( +"Administrative Templates Extension" => "35378EAC-683F-11D2-A89A-00C04FBBCFA2", +"Disk Quotas" => "3610EDA5-77EF-11D2-8DC5-00C04FA31A66", +"EFS Recovery" => "B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A", +"Folder Redirection" => "25537BA6-77A8-11D2-9B6C-0000F8080861", +"IP Security" => "E437BC1C-AA7D-11D2-A382-00C04F991E27", +"Internet Explorer Maintenance" => "A2E30F80-D7DE-11d2-BBDE-00C04F86AE3B", +"QoS Packet Scheduler" => "426031c0-0b47-4852-b0ca-ac3d37bfcb39", +"Scripts" => "42B5FAAE-6536-11D2-AE5A-0000F87571E3", +"Security" => "827D319E-6EAC-11D2-A4EA-00C04F79F83A", +"Software Installation" => "C6DC5466-785A-11D2-84D0-00C04FB169F7", +); + +# guess work +my %ads_gpcextensions = ( +"Administrative Templates" => "0F6B957D-509E-11D1-A7CC-0000F87571E3", +"Certificates" => "53D6AB1D-2488-11D1-A28C-00C04FB94F17", +"EFS recovery policy processing" => "B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A", +"Folder Redirection policy processing" => "25537BA6-77A8-11D2-9B6C-0000F8080861", +"Folder Redirection" => "88E729D6-BDC1-11D1-BD2A-00C04FB9603F", +"Registry policy processing" => "35378EAC-683F-11D2-A89A-00C04FBBCFA2", +"Remote Installation Services" => "3060E8CE-7020-11D2-842D-00C04FA372D4", +"Security Settings" => "803E14A0-B4FB-11D0-A0D0-00A0C90F574B", +"Security policy processing" => "827D319E-6EAC-11D2-A4EA-00C04F79F83A", +"unknown" => "3060E8D0-7020-11D2-842D-00C04FA372D4", +"unknown2" => "53D6AB1B-2488-11D1-A28C-00C04FB94F17", +); + +my %ads_gpo_default_guids = ( +"Default Domain Policy" => "31B2F340-016D-11D2-945F-00C04FB984F9", +"Default Domain Controllers Policy" => "6AC1786C-016F-11D2-945F-00C04fB984F9", +"mist" => "61718096-3D3F-4398-8318-203A48976F9E", +); + +my %ads_uf = ( + "UF_SCRIPT" => 0x00000001, + "UF_ACCOUNTDISABLE" => 0x00000002, +# "UF_UNUSED_1" => 0x00000004, + "UF_HOMEDIR_REQUIRED" => 0x00000008, + "UF_LOCKOUT" => 0x00000010, + "UF_PASSWD_NOTREQD" => 0x00000020, + "UF_PASSWD_CANT_CHANGE" => 0x00000040, + "UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED" => 0x00000080, + "UF_TEMP_DUPLICATE_ACCOUNT" => 0x00000100, + "UF_NORMAL_ACCOUNT" => 0x00000200, +# "UF_UNUSED_2" => 0x00000400, + "UF_INTERDOMAIN_TRUST_ACCOUNT" => 0x00000800, + "UF_WORKSTATION_TRUST_ACCOUNT" => 0x00001000, + "UF_SERVER_TRUST_ACCOUNT" => 0x00002000, +# "UF_UNUSED_3" => 0x00004000, +# "UF_UNUSED_4" => 0x00008000, + "UF_DONT_EXPIRE_PASSWD" => 0x00010000, + "UF_MNS_LOGON_ACCOUNT" => 0x00020000, + "UF_SMARTCARD_REQUIRED" => 0x00040000, + "UF_TRUSTED_FOR_DELEGATION" => 0x00080000, + "UF_NOT_DELEGATED" => 0x00100000, + "UF_USE_DES_KEY_ONLY" => 0x00200000, + "UF_DONT_REQUIRE_PREAUTH" => 0x00400000, + "UF_PASSWORD_EXPIRED" => 0x00800000, + "UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION" => 0x01000000, + "UF_NO_AUTH_DATA_REQUIRED" => 0x02000000, +# "UF_UNUSED_8" => 0x04000000, +# "UF_UNUSED_9" => 0x08000000, +# "UF_UNUSED_10" => 0x10000000, +# "UF_UNUSED_11" => 0x20000000, +# "UF_UNUSED_12" => 0x40000000, +# "UF_UNUSED_13" => 0x80000000, +); + +my %ads_grouptype = ( + "GROUP_TYPE_BUILTIN_LOCAL_GROUP" => 0x00000001, + "GROUP_TYPE_ACCOUNT_GROUP" => 0x00000002, + "GROUP_TYPE_RESOURCE_GROUP" => 0x00000004, + "GROUP_TYPE_UNIVERSAL_GROUP" => 0x00000008, + "GROUP_TYPE_APP_BASIC_GROUP" => 0x00000010, + "GROUP_TYPE_APP_QUERY_GROUP" => 0x00000020, + "GROUP_TYPE_SECURITY_ENABLED" => 0x80000000, +); + +my %ads_atype = ( + "ATYPE_NORMAL_ACCOUNT" => 0x30000000, + "ATYPE_WORKSTATION_TRUST" => 0x30000001, + "ATYPE_INTERDOMAIN_TRUST" => 0x30000002, + "ATYPE_SECURITY_GLOBAL_GROUP" => 0x10000000, + "ATYPE_DISTRIBUTION_GLOBAL_GROUP" => 0x10000001, + "ATYPE_DISTRIBUTION_UNIVERSAL_GROUP" => 0x10000001, # ATYPE_DISTRIBUTION_GLOBAL_GROUP + "ATYPE_SECURITY_LOCAL_GROUP" => 0x20000000, + "ATYPE_DISTRIBUTION_LOCAL_GROUP" => 0x20000001, + "ATYPE_ACCOUNT" => 0x30000000, # ATYPE_NORMAL_ACCOUNT + "ATYPE_GLOBAL_GROUP" => 0x10000000, # ATYPE_SECURITY_GLOBAL_GROUP + "ATYPE_LOCAL_GROUP" => 0x20000000, # ATYPE_SECURITY_LOCAL_GROUP +); + +my %ads_gtype = ( + "GTYPE_SECURITY_BUILTIN_LOCAL_GROUP" => 0x80000005, + "GTYPE_SECURITY_DOMAIN_LOCAL_GROUP" => 0x80000004, + "GTYPE_SECURITY_GLOBAL_GROUP" => 0x80000002, + "GTYPE_SECURITY_UNIVERSAL_GROUP" => 0x80000008, + "GTYPE_DISTRIBUTION_GLOBAL_GROUP" => 0x00000002, + "GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP" => 0x00000004, + "GTYPE_DISTRIBUTION_UNIVERSAL_GROUP" => 0x00000008, +); + +my %munged_dial = ( + "CtxCfgPresent" => \&dump_int, + "CtxCfgFlags1" => \&dump_int, + "CtxCallback" => \&dump_string, + "CtxShadow" => \&dump_string, + "CtxMaxConnectionTime" => \&dump_int, + "CtxMaxDisconnectionTime"=> \&dump_int, + "CtxMaxIdleTime" => \&dump_int, + "CtxKeyboardLayout" => \&dump_int, + "CtxMinEncryptionLevel" => \&dump_int, + "CtxWorkDirectory" => \&dump_string, + "CtxNWLogonServer" => \&dump_string, + "CtxWFHomeDir" => \&dump_string, + "CtxWFHomeDirDrive" => \&dump_string, + "CtxWFProfilePath" => \&dump_string, + "CtxInitialProgram" => \&dump_string, + "CtxCallbackNumber" => \&dump_string, +); + +$SIG{__WARN__} = sub { + use Carp; + Carp::cluck (shift); +}; + +# if there is data missing, we try to autodetect with samba-tools (if installed) +# this might fill up workgroup, machine, realm +get_samba_info(); + +# get a workgroup +$workgroup = $workgroup || $opt_workgroup || ""; + +# get the server +$server = process_servername($opt_host) || + detect_server($workgroup,$opt_realm) || + die "please define server to query with -h host\n"; + + +# get the base +$base = defined($opt_base)? $opt_base : "" || + get_base_from_rootdse($server,$dse); + +# get the realm +$realm = $opt_realm || + get_realm_from_rootdse($server,$dse); + +# get sasl mechs +my @sasl_mechs = get_sasl_mechs_from_rootdse($server,$dse); +my $sasl_mech = "GSSAPI"; +if ($opt_saslmech) { + $sasl_mech = sprintf("%s", (check_sasl_mech($opt_saslmech) == 0)?uc($opt_saslmech):""); +} + +# set bind type +my $sasl_bind = 1 if (!$opt_simpleauth); + +# get username +my $user = check_user($opt_user) || $ENV{'USER'} || ""; + +# gen upn +my $upn = sprintf("%s", gen_upn($opt_machine ? "$machine\$" : $user, $realm)); + +# get binddn +$binddn = $opt_binddn || $upn; + +# get the password +$password = $password || $opt_password; +if (!$password) { + $password = $opt_machine ? get_machine_password($workgroup) : get_password(); +} + +my %attr_handler = ( + "Token-Groups-No-GC-Acceptable" => \&dump_sid, #wrong name + "accountExpires" => \&dump_nttime, + "attributeSecurityGUID" => \&dump_guid, + "badPasswordTime" => \&dump_nttime, + "creationTime" => \&dump_nttime, + "currentTime" => \&dump_timestr, + "domainControllerFunctionality" => \&dump_ds_func, + "domainFunctionality" => \&dump_ds_func, + "fRSReplicaSetGUID" => \&dump_guid, + "fRSReplicaSetType" => \&dump_frstype, + "fRSVersionGUID" => \&dump_guid, + "flags" => \&dump_gpflags, # fixme: possibly only on gpos! + "forceLogoff" => \&dump_nttime_abs, + "forestFunctionality" => \&dump_ds_func, +# "gPCMachineExtensionNames" => \&dump_gpcextensions, +# "gPCUserExtensionNames" => \&dump_gpcextensions, + "gPLink" => \&dump_gplink, + "gPOptions" => \&dump_gpoptions, + "groupType" => \&dump_gtype, + "instanceType" => \&dump_instance_type, + "lastLogon" => \&dump_nttime, + "lastLogonTimestamp" => \&dump_nttime, + "lockOutObservationWindow" => \&dump_nttime_abs, + "lockoutDuration" => \&dump_nttime_abs, + "lockoutTime" => \&dump_nttime, +# "logonHours" => \&dump_logonhours, + "maxPwdAge" => \&dump_nttime_abs, + "minPwdAge" => \&dump_nttime_abs, + "modifyTimeStamp" => \&dump_timestr, + "msDS-Behavior-Version" => \&dump_ds_func, #unsure + "msDS-User-Account-Control-Computed" => \&dump_uacc, + "msDS-SupportedEncryptionTypes" => \&dump_enctypes, + "mS-DS-CreatorSID" => \&dump_sid, +# "msRADIUSFramedIPAddress" => \&dump_ipaddr, +# "msRASSavedFramedIPAddress" => \&dump_ipaddr, + "netbootGUID" => \&dump_guid, + "nTMixedDomain" => \&dump_mixed_domain, + "nTSecurityDescriptor" => \&dump_secdesc, + "objectGUID" => \&dump_guid, + "objectSid" => \&dump_sid, + "pKT" => \&dump_pkt, + "pKTGuid" => \&dump_guid, + "pwdLastSet" => \&dump_nttime, + "pwdProperties" => \&dump_pwdproperties, + "sAMAccountType" => \&dump_atype, + "schemaIDGUID" => \&dump_guid, + "sDRightsEffective" => \&dump_sdeffective, + "securityIdentifier" => \&dump_sid, + "serverState" => \&dump_serverstate, + "supportedCapabilities", => \&dump_capabilities, + "supportedControl", => \&dump_controls, + "supportedExtension", => \&dump_extension, + "systemFlags" => \&dump_systemflags, + "tokenGroups", => \&dump_sid, + "tokenGroupsGlobalAndUniversal" => \&dump_sid, + "tokenGroupsNoGCAcceptable" => \&dump_sid, + "trustAttributes" => \&dump_trustattr, + "trustDirection" => \&dump_trustdirection, + "trustType" => \&dump_trusttype, + "uASCompat" => \&dump_uascompat, + "userAccountControl" => \&dump_uac, + "userCertificate" => \&dump_cert, + "userFlags" => \&dump_uf, + "userParameters" => \&dump_munged_dial, + "whenChanged" => \&dump_timestr, + "whenCreated" => \&dump_timestr, +# "dSCorePropagationData" => \&dump_timestr, +); + + + +################ +# subfunctions # +################ + +sub usage { + print "usage: $0 [--asq] [--base|-b base] [--debug level] [--debug level] [--DN|-D binddn] [--extendeddn|-e] [--help] [--host|-h host] [--machine|-P] [--metadata|-m] [--nodiffs] [--notify|-n] [--password|-w password] [--port port] [--rawdisplay] [--realm|-R realm] [--rootdse] [--saslmech|-Y saslmech] [--schema|-c] [--scope|-s scope] [--simpleauth|-x] [--starttls|-Z] [--user|-U user] [--wknguid] [--workgroup|-k workgroup] filter [attrs]\n"; + print "\t--asq [attribute]\n\t\tAttribute to use for a attribute scoped query (LDAP_SERVER_ASQ_OID)\n"; + print "\t--base|-b [base]\n\t\tUse base [base]\n"; + print "\t--debug [level]\n\t\tUse debuglevel (for Net::LDAP)\n"; + print "\t--domain_scope\n\t\tLimit LDAP search to local domain (LDAP_SERVER_DOMAIN_SCOPE_OID)\n"; + print "\t--DN|-D [binddn]\n\t\tUse binddn or principal\n"; + print "\t--extendeddn|-e [value]\n\t\tDisplay extended dn (LDAP_SERVER_EXTENDED_DN_OID)\n"; + print "\t--fastbind\n\t\tDo LDAP fast bind using LDAP_SERVER_FAST_BIND_OID extension\n"; + print "\t--help\n\t\tDisplay help page\n"; + print "\t--host|-h [host]\n\t\tQuery Host [host] (either a hostname or an LDAP uri)\n"; + print "\t--machine|-P\n\t\tUse samba3 machine account stored in $secrets_tdb (needs root access)\n"; + print "\t--metdata|-m\n\t\tDisplay replication metadata\n"; + print "\t--nodiffs\n\t\tDisplay no diffs but full entry dump when running in notify mode\n"; + print "\t--notify|-n\n\t\tActivate asynchronous change notification (LDAP_SERVER_NOTIFICATION_OID)\n"; + print "\t--paging [pagesize]\n\t\tUse paged results when searching\n"; + print "\t--password|-w [password]\n\t\tUse [password] for binddn\n"; + print "\t--port [port]\n\t\tUse [port] when connecting ADS\n"; + print "\t--rawdisplay\n\t\tDo not interpret values\n"; + print "\t--realm|-R [realm]\n\t\tUse [realm] when trying to construct bind-principal\n"; + print "\t--rootdse\n\t\tDisplay RootDSE (anonymously)\n"; + print "\t--saslmech|-Y [saslmech]\n\t\tUse SASL Mechanism [saslmech] when binding\n"; + print "\t--schema|-c\n\t\tDisplay DSE-Schema\n"; + print "\t--scope|-s [scope]\n\t\tUse scope [scope] (sub, base, one)\n"; + print "\t--simpleauth|-x\n\t\tUse simple bind (otherwise SASL binds are performed)\n"; + print "\t--starttls|-Z\n\t\tUse Start TLS extended operation to secure LDAP traffic\n"; + print "\t--user|-U [user]\n\t\tUse [user]\n"; + print "\t--wknguid\n\t\tDisplay well known guids\n"; + print "\t--workgroup|-k [workgroup]\n\t\tWhen LDAP-Server is not known try to find a Domain-Controller for [workgroup]\n"; +} + +sub write_ads_list { + my ($mod,$attr,$value) = @_; + my $ofh = select(STDOUT); + $~ = "ADS_LIST"; + select($ofh); + write(); + +format ADS_LIST = +@<<<< @>>>>>>>>>>>>>>>>>>>>>>>: @* +$mod, $attr, $value +. +} + +sub write_ads { + my ($mod,$attr,$value) = @_; + my $ofh = select(STDOUT); + $~ = "ADS"; + select($ofh); + write(); + +format ADS = +@<<<< @>>>>>>>>>>>>>>>>>>>>>>>: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +$mod, $attr, $value +~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $value +. +} + +sub detect_server { + + my $workgroup = shift; + my $realm = shift; + my $result; + my $found; + + # try net cache (nbt records) + if ( -x $net && $workgroup ) { + my $key = sprintf("NBT/%s#1C", uc($workgroup)); + chomp($result = `$net cache search $key 2>&1 /dev/null`); + $result =~ s/^.*Value: //; + $result =~ s/:.*//; + return $result if $result; + printf("%10s query failed for [%s]\n", "net cache", $key); + } + + # try dns SRV entries + if ( -x $dig && $realm ) { + my $key = sprintf("_ldap._tcp.%s", lc($realm)); + chomp($result = `$dig $key SRV +short +search | egrep "^[0-9]" | head -1`); + $result =~ s/.* //g; + $result =~ s/.$//g; + return $result if $result; + printf("%10s query failed for [%s]\n", "dns", $key); + } + + # try netbios broadcast query + if ( -x $nmblookup && $workgroup ) { + my $key = sprintf("%s#1C", uc($workgroup)); + my $pattern = sprintf("%s<1c>", uc($workgroup)); + chomp($result = `$nmblookup $key -d 0 | grep '$pattern'`); + $result =~ s/\s.*//; + return $result if $result; + printf("%10s query failed for [%s]\n", "nmblookup", $key); + } + + return ""; +} + +sub get_samba_info { + + if (! -x $testparm) { return -1; } + + my $tmp; + open(TESTPARM, "$testparm -s -v 2> /dev/null |"); + while (my $line = <TESTPARM>) { + chomp($line); + if ($line =~ /netbios name/) { + ($tmp, $machine) = split(/=/, $line); + $machine =~ s/\s+|\t+//g; + } + if ($line =~ /realm/) { + ($tmp, $realm) = split(/=/, $line); + $realm =~ s/\s+|\t+//g; + } + if ($line =~ /workgroup/) { + ($tmp, $workgroup) = split(/=/, $line); + $workgroup =~ s/\s+|\t+//g; + } + } + close(TESTPARM); + return 0; +} + +sub gen_upn { + my $machine = shift; + my $realm = shift; + if ($machine && $realm) { + return sprintf("%s\@%s", lc($machine), uc($realm)); + }; + return undef; +} + +sub get_password { + if (!$password && $opt_simpleauth && check_ticket($user)) { + return prompt_password($user); + } + return ""; +} + +sub get_user { + my $user = shift || prompt_user(); + return $user; +} + +sub get_machine_password { + + my $workgroup = shift || ""; + $workgroup = uc($workgroup); + + my ($found, $tmp); + -x $tdbdump || die "tdbdump is not installed. cannot proceed autodetection\n"; + -r $secrets_tdb || die "cannot read $secrets_tdb. cannot proceed autodetection\n"; + + # get machine-password + my $key = sprintf("SECRETS/MACHINE_PASSWORD/%s", $workgroup); + open(SECRETS,"$tdbdump $secrets_tdb |"); + while(my $line = <SECRETS>) { + chomp($line); + if ($found) { + $line =~ s/\\00//; + ($line,$password) = split(/"/, $line); + last; + } + if ($line =~ /$key/) { + $found = 1; + } + } + close(SECRETS); + + if ($found) { + print "Successfully autodetected machine password for workgroup: $workgroup\n"; + return $password; + } else { + warn "No machine password available for $workgroup\n"; + } + return ""; +} + +sub prompt_password { + + my $acct = shift || ""; + if ($acct =~ /\%/) { + ($acct, $password) = split(/\%/, $acct); + return $password; + } + system "stty -echo"; + print "Enter password for $acct:"; + my $password = <STDIN>; + chomp($password); + print "\n"; + system "stty echo"; + return $password; +} + +sub prompt_user { + + print "Enter Username:"; + my $user = <STDIN>; + chomp($user); + print "\n"; + return $user; +} + +sub check_ticket { + return 0; + # works only for heimdal + return system("$klist -t"); +} + +sub get_ticket { + + my $KRB5_CONFIG = "/tmp/.krb5.conf.telads-$<"; + + open(KRB5CONF, "> $KRB5_CONFIG") || die "cannot write $KRB5_CONFIG"; + printf KRB5CONF "# autogenerated by $0\n"; + printf KRB5CONF "[libdefaults]\n\tdefault_realm = %s\n\tclockskew = %d\n", uc($realm), 60*60; + printf KRB5CONF "[realms]\n\t%s = {\n\t\tkdc = %s\n\t}\n", uc($realm), $server; + close(KRB5CONF); + + if ( system("KRB5_CONFIG=$KRB5_CONFIG $kinit $user") != 0) { + return -1; + } + + return 0; +} + +sub check_user { + my $acct = shift || ""; + if ($acct =~ /\%/) { + ($acct, $password) = split(/\%/, $acct); + } + return $acct; +} + +sub check_root_dse($$$@) { + + # bogus function?? + my $server = shift || ""; + $dse = shift || get_dse($server) || return -1; + my $attr = shift || die "unknown query"; + my @array = @_; + + my $dse_list = $dse->get_value($attr, asref => '1'); + my @dse_array = @$dse_list; + + foreach my $i (@array) { + # we could use -> supported_control but this + # is only available in newer versions of perl-ldap +# if ( ! $dse->supported_control( $i ) ) { + if ( grep(/$i->type()/, @dse_array) ) { + printf("required \"$attr\": %s is not supported by ADS-server.\n", $i->type()); + return -1; + } + } + return 0; +} + +sub check_ctrls ($$@) { + my $server = shift; + my $dse = shift; + my @array = @_; + return check_root_dse($server, $dse, "supportedControl", @array); +} + +sub check_exts ($$@) { + my $server = shift; + my $dse = shift; + my @array = @_; + return check_root_dse($server, $dse, "supportedExtension", @array); +} + +sub get_base_from_rootdse { + + my $server = shift || ""; + $dse = shift || get_dse($server,$async_ldap_hd) || return -1; + return $dse->get_value($opt_dump_schema ? 'schemaNamingContext': + 'defaultNamingContext'); +} + +sub get_realm_from_rootdse { + + my $server = shift || ""; + $dse = shift || get_dse($server,$async_ldap_hd) || return -1; + my $service = $dse->get_value('ldapServiceName') || ""; + if ($service) { + my ($t,$realm) = split(/\@/, $service); + return $realm; + } else { + die "very odd: could not get realm"; + } +} + +sub get_sasl_mechs_from_rootdse { + + my $server = shift || ""; + $dse = shift || get_dse($server,$async_ldap_hd) || return -1; + my $mechs = $dse->get_value('supportedSASLMechanisms', asref => 1); + return @$mechs; +} + +sub get_dse { + + my $server = shift || return undef; + $async_ldap_hd = shift || get_ldap_hd($server,1); + if (!$async_ldap_hd) { + print "oh, no connection\n"; + return undef; + } + my $mesg = $async_ldap_hd->bind() || die "cannot bind\n"; + if ($mesg->code) { die "failed to bind\n"; }; + my $dse = $async_ldap_hd->root_dse( attrs => ['*', "supportedExtension", "supportedFeatures" ] ); + + return $dse; +} + +sub process_servername { + + my $name = shift || return ""; + if ($name =~ /^ldaps:\/\//i ) { + $name =~ s#^ldaps://##i; + $uri = sprintf("%s://%s", "ldaps", $name); + } else { + $name =~ s#^ldap://##i; + $uri = sprintf("%s://%s", "ldap", $name); + } + return $name; +} + +sub get_ldap_hd { + + my $server = shift || return undef; + my $async = shift || "0"; + my $hd; + die "uri unavailable" if (!$uri); + if ($uri =~ /^ldaps:\/\//i ) { + $port = $port || 636; + use Net::LDAPS; + $hd = Net::LDAPS->new( $server, async => $async, port => $port ) || + die "host $server not available: $!"; + } else { + $port = $port || 389; + $hd = Net::LDAP->new( $server, async => $async, port => $port ) || + die "host $server not available: $!"; + } + $hd->debug($opt_debug); + if ($opt_starttls) { + $hd->start_tls( verify => 'none' ); + } + + return $hd; +} + +sub get_sasl_hd { + + if (!$have_sasl) { + print "no sasl support\n"; + return undef; + } + + my $hd; + if ($sasl_mech && $sasl_mech eq "GSSAPI") { + my $user = sprintf("%s\@%s", $user, uc($realm)); + if (check_ticket($user) != 0 && get_ticket($user) != 0) { + print "Could not get Kerberos ticket for user [$user]\n"; + return undef; + } + + $hd = Authen::SASL->new( mechanism => 'GSSAPI' ) || die "nope"; + my $conn = $hd->client_new("ldap", $server); + + if ($conn->code == -1) { + printf "%s\n", $conn->error(); + return undef; + }; + + } elsif ($sasl_mech) { + + # here comes generic sasl code + $hd = Authen::SASL->new( mechanism => $sasl_mech, + callback => { + user => \&get_user, + pass => \&get_password + } + ) || die "nope"; + } else { + $sasl_bind = 0; + print "no supported SASL mechanism found (@sasl_mechs).\n"; + print "falling back to simple bind.\n"; + return undef; + } + + return $hd; +} + +sub check_sasl_mech { + my $mech_check = shift; + my $have_mech = 0; + foreach my $mech (@sasl_mechs) { + $have_mech = 1 if ($mech eq uc($mech_check)); + } + if (!$have_mech) { + return -1; + } + return 0; +} + +sub store_result ($) { + + my $entry = shift; + return if (!$entry); + $entry_store{$entry->dn} = $entry; +} + +sub display_result_diff ($) { + + my $entry_new = shift; + return if ( !$entry_new); + + if ( !exists $entry_store{$entry_new->dn}) { + print "can't display any differences yet. full dump...\n"; + display_entry_generic($entry_new); + return; + } + + my $entry_old = $entry_store{$entry_new->dn}; + + foreach my $attr (sort $entry_new->attributes) { + if ( $entry_new->exists($attr) && ! $entry_old->exists($attr)) { + display_attr_generic("add:\t", $entry_new, $attr); + next; + } + } + + foreach my $attr (sort $entry_old->attributes) { + if (! $entry_new->exists($attr) && $entry_old->exists($attr)) { + display_attr_generic("del:\t", $entry_old, $attr); + next; + } + + # now check for all values if they have changed, display changes + my ($old_vals, $new_vals, @old_vals, @new_vals, %old, %new); + + $old_vals = $entry_old->get_value($attr, asref => 1); + @old_vals = @$old_vals; + $new_vals = $entry_new->get_value($attr, asref => 1); + @new_vals = @$new_vals; + + if (scalar(@old_vals) == 1 && scalar(@new_vals) == 1) { + if ($old_vals[0] ne $new_vals[0]) { + display_attr_generic("old:\t", $entry_old, $attr); + display_attr_generic("new:\t", $entry_new, $attr); + } + next; + } + + # handle multivalued diffs + foreach my $val (@old_vals) { $old{$val} = "dummy"; }; + foreach my $val (@new_vals) { $new{$val} = "dummy"; }; + foreach my $val (sort keys %new) { + if (!exists $old{$val}) { + display_value_generic("add:\t", $attr, $val); + } + } + foreach my $val (sort keys %old) { + if (!exists $new{$val}) { + display_value_generic("del:\t", $attr, $val); + } + } + } + print "\n"; + +} + +sub sid2string ($) { + + # Fix from Michael James <michael@james.st> + my $binary_sid = shift; + my($sid_rev, $num_auths, $id1, $id2, @ids) = unpack("H2 H2 n N V*", $binary_sid); + my $sid_string = join("-", "S", hex($sid_rev), ($id1<<32)+$id2, @ids); + return $sid_string; + +} + +sub string_to_guid { + my $string = shift; + return undef unless $string =~ /([0-9,a-z]{8})-([0-9,a-z]{4})-([0-9,a-z]{4})-([0-9,a-z]{2})([0-9,a-z]{2})-([0-9,a-z]{2})([0-9,a-z]{2})([0-9,a-z]{2})([0-9,a-z]{2})([0-9,a-z]{2})([0-9,a-z]{2})/i; + + return pack("I", hex $1) . + pack("S", hex $2) . + pack("S", hex $3) . + pack("C", hex $4) . + pack("C", hex $5) . + pack("C", hex $6) . + pack("C", hex $7) . + pack("C", hex $8) . + pack("C", hex $9) . + pack("C", hex $10) . + pack("C", hex $11); + +# print "$1\n$2\n$3\n$4\n$5\n$6\n$7\n$8\n$9\n$10\n$11\n"; +} + +sub bindstring_to_guid { + my $str = shift; + return pack("H2 H2 H2 H2 H2 H2 H2 H2 H2 H2 H2 H2 H2 H2 H2 H2", + substr($str,0,2), + substr($str,2,2), + substr($str,4,2), + substr($str,6,2), + substr($str,8,2), + substr($str,10,2), + substr($str,12,2), + substr($str,14,2), + substr($str,16,2), + substr($str,18,2), + substr($str,20,2), + substr($str,22,2), + substr($str,24,2), + substr($str,26,2), + substr($str,28,2), + substr($str,30,2)); +} + +sub guid_to_string { + my $guid = shift; + my $string = sprintf "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + unpack("I", $guid), + unpack("S", substr($guid, 4, 2)), + unpack("S", substr($guid, 6, 2)), + unpack("C", substr($guid, 8, 1)), + unpack("C", substr($guid, 9, 1)), + unpack("C", substr($guid, 10, 1)), + unpack("C", substr($guid, 11, 1)), + unpack("C", substr($guid, 12, 1)), + unpack("C", substr($guid, 13, 1)), + unpack("C", substr($guid, 14, 1)), + unpack("C", substr($guid, 15, 1)); + return lc($string); +} + +sub guid_to_bindstring { + my $guid = shift; + return unpack("H" . 2 * length($guid), $guid), +} + +sub dump_wknguid { + print "Dumping Well known GUIDs:\n"; + foreach my $wknguid (keys %wknguids) { + + my $guid = bindstring_to_guid($wknguids{$wknguid}); + my $str = guid_to_string($guid); + my $back = guid_to_bindstring($guid); + + printf "wkguid: %s\n", $wknguid; + printf "bind_string format: %s\n", $wknguids{$wknguid}; + printf "string format: %s\n", guid_to_string($guid); + printf "back to bind_string:%s\n", guid_to_bindstring($guid); + + printf "use base: \"<WKGUID=%s,%s>\"\n", guid_to_bindstring($guid), $base; + } +} + +sub gen_bitmask_string_format($%) { + my $mod = shift; + my (%tmp) = @_; + my @list; + foreach my $key (sort keys %tmp) { + push(@list, sprintf("%s %s", $tmp{$key}, $key)); + } + return join("\n$mod$tabsize",@list); +} + + +sub nt_to_unixtime ($) { + # the number of 100 nanosecond intervals since jan. 1. 1601 (utc) + my $t64 = shift; + $t64 =~ s/(.+).{7,7}/$1/; + $t64 -= 11644473600; + return $t64; +} + +sub dump_equal { + my $val = shift; + my $mod = shift || die "no mod"; + my (%header) = @_; + my %tmp; + my $found = 0; + foreach my $key (keys %header) { + if ($header{$key} eq $val) { + $tmp{"($val)"} = $key; + $found = 1; + last; + } + } + if (!$found) { $tmp{$val} = ""; }; + return gen_bitmask_string_format($mod,%tmp); +} + +sub dump_bitmask { + my $op = shift || die "no op"; + my $val = shift; + my $mod = shift || die "no mod"; + my (%header) = @_; + my %tmp; + $tmp{""} = sprintf("%s (0x%08x)", $val, $val); + foreach my $key (sort keys %header) { # sort by val ! + my $val_hex = sprintf("0x%08x", $header{$key}); + if ($op eq "&") { + $tmp{"$key ($val_hex)"} = ( $val & $header{$key} ) ? $set:$unset; + } elsif ($op eq "==") { + $tmp{"$key ($val_hex)"} = ( $val == $header{$key} ) ? $set:$unset; + } else { + print "unknown operator: $op\n"; + return; + } + } + return gen_bitmask_string_format($mod,%tmp); +} + +sub dump_bitmask_and { + return dump_bitmask("&",@_); +} + +sub dump_bitmask_equal { + return dump_bitmask("==",@_); +} + +sub dump_uac { + return dump_bitmask_and(@_,%ads_uf); # ads_uf ? +} + +sub dump_uascompat { + return dump_bitmask_equal(@_,%ads_uascompat); +} + +sub dump_gpoptions { + return dump_bitmask_equal(@_,%ads_gpoptions); +} + +sub dump_gpflags { + return dump_bitmask_equal(@_,%ads_gpflags); +} + +sub dump_uacc { + return dump_bitmask_equal(@_,%ads_uacc); +} + +sub dump_enctypes { + return dump_bitmask_and(@_,%ads_enctypes); +} + +sub dump_uf { + return dump_bitmask_and(@_,%ads_uf); +} + +sub dump_gtype { + my $ret = dump_bitmask_and(@_,%ads_grouptype); + $ret .= "\n$tabsize\t"; + $ret .= dump_bitmask_equal(@_,%ads_gtype); + return $ret; +} + +sub dump_atype { + return dump_bitmask_equal(@_,%ads_atype); +} + +sub dump_controls { + return dump_equal(@_,%ads_controls); +} + +sub dump_capabilities { + return dump_equal(@_,%ads_capabilities); +} + +sub dump_extension { + return dump_equal(@_,%ads_extensions); +} + +sub dump_systemflags { + return dump_bitmask_and(@_,%ads_systemflags); +} + +sub dump_instance_type { + return dump_bitmask_and(@_,%ads_instance_type); +} + +sub dump_ds_func { + return dump_bitmask_equal(@_,%ads_ds_func); +} + +sub dump_serverstate { + return dump_bitmask_equal(@_,%ads_serverstate); +} + +sub dump_sdeffective { + return dump_bitmask_and(@_,%ads_sdeffective); +} + +sub dump_trustattr { + return dump_bitmask_equal(@_,%ads_trustattrs); +} + +sub dump_trusttype { + return dump_bitmask_equal(@_,%ads_trusttype); +} + +sub dump_trustdirection { + return dump_bitmask_equal(@_,%ads_trustdirection); +} + +sub dump_pwdproperties { + return dump_bitmask_and(@_,%ads_pwdproperties); +} + +sub dump_frstype { + return dump_bitmask_equal(@_,%ads_frstypes) +} + +sub dump_mixed_domain { + return dump_bitmask_equal(@_,%ads_mixed_domain); +} + +sub dump_sid { + my $bin_sid = shift; + return sid2string($bin_sid); +} + +sub dump_guid { + my $guid = shift; + return guid_to_string($guid); +} + +sub dump_secdesc { + my $val = shift; + return "FIXME: write sddl-converter!"; +} + +sub dump_nttime { + my $nttime = shift; + if ($nttime == 0) { + return sprintf("%s (%s)", "never", $nttime); + } + my $localtime = localtime(nt_to_unixtime($nttime)); + return sprintf("%s (%s)", $localtime, $nttime); +} + +sub dump_nttime_abs { + if ($_[0] == 9223372036854775807) { + return sprintf("%s (%s)", "now", $_[0]); + } + if ($_[0] == -9223372036854775808 || $_[0] == 0) { # 0x7FFFFFFFFFFFFFFF + return sprintf("%s (%s)", "never", $_[0]); + } + # FIXME: actually *do* abs time ! + return dump_nttime($_[0]); +} + +sub dump_timestr { + my $time = shift; + if ($time eq "16010101000010.0Z") { + return sprintf("%s (%s)", "never", $time); + } + my ($year,$mon,$mday,$hour,$min,$sec,$zone) = + unpack('a4 a2 a2 a2 a2 a2 a4', $time); + $mon -= 1; + my $localtime = localtime(timegm($sec,$min,$hour,$mday,$mon,$year)); + return sprintf("%s (%s)", $localtime, $time); +} + +sub dump_string { + return $_[0]; +} + +sub dump_int { + return sprintf("%d", $_[0]); +} + +sub dump_munged_dial { + my $dial = shift; + return "FIXME! decode this"; +} + +sub dump_cert { + + my $cert = shift; + open(OPENSSL, "| /usr/bin/openssl x509 -text -inform der"); + print OPENSSL $cert; + close(OPENSSL); + return ""; +} + +sub dump_pkt { + my $pkt = shift; + return "not yet"; + printf("%s: ", $pkt); + printf("%02X", $pkt); + +} + +sub dump_gplink { + + my $gplink = shift; + my $gplink_mod = $gplink; + my @links = split("\\]\\[", $gplink_mod); + foreach my $link (@links) { + $link =~ s/^\[|\]$//g; + my ($ldap_link, $opt) = split(";", $link); + my @array = ( "$opt", "\t" ); + printf("%slink: %s, opt: %s\n", $tabsize, $ldap_link, dump_bitmask_and(@array, %ads_gplink_opts)); + } + return $gplink; +} + +sub construct_filter { + + my $tmp = shift; + + if (!$tmp || $opt_notify) { + return "(objectclass=*)"; + } + + if ($tmp && $tmp !~ /^.*\=/) { + return "(ANR=$tmp)"; + } + + return $tmp; + # (&(objectCategory=person) + # (userAccountControl:$ads_matching_rules{LDAP_MATCHING_RULE_BIT_AND}:=2)) +} + +sub construct_attrs { + + my @attrs = @_; + + if (!@attrs) { + push(@attrs,"*"); + } + + if ($opt_notify) { + push(@attrs,"uSNChanged"); + } + + if ($opt_display_metadata) { + push(@attrs,"msDS-ReplAttributeMetaData"); + push(@attrs,"replPropertyMetaData"); + } + + if ($opt_verbose) { + push(@attrs,"nTSecurityDescriptor"); + push(@attrs,"msDS-KeyVersionNumber"); + push(@attrs,"msDS-User-Account-Control-Computed"); + push(@attrs,"modifyTimeStamp"); + } + + return sort @attrs; +} + +sub print_header { + + print "\n"; + printf "%10s: %s\n", "uri", $uri; + printf "%10s: %s\n", "port", $port; + printf "%10s: %s\n", "base", $base; + printf "%10s: %s\n", $sasl_bind ? "principal" : "binddn", $sasl_bind ? $upn : $binddn; + printf "%10s: %s\n", "password", $password; + printf "%10s: %s\n", "bind-type", $sasl_bind ? "SASL" : "simple"; + printf "%10s: %s\n", "sasl-mech", $sasl_mech if ($sasl_mech); + printf "%10s: %s\n", "filter", $filter; + printf "%10s: %s\n", "scope", $scope; + printf "%10s: %s\n", "attrs", join(", ", @attrs); + printf "%10s: %s\n", "controls", join(", ", @ctrls_s); + printf "%10s: %s\n", "page_size", $opt_paging if ($opt_paging); + printf "%10s: %s\n", "start_tls", $opt_starttls ? "yes" : "no"; + printf "\n"; +} + +sub gen_controls { + + # setup attribute-scoped query control + my $asq_asn = Convert::ASN1->new; + $asq_asn->prepare( + q< asq ::= SEQUENCE { + sourceAttribute OCTET_STRING + } + > + ); + my $ctl_asq_val = $asq_asn->encode( sourceAttribute => $opt_asq); + my $ctl_asq = Net::LDAP::Control->new( + type => $ads_controls{'LDAP_SERVER_ASQ_OID'}, + critical => 'true', + value => $ctl_asq_val); + + + # setup extended dn control + my $asn_extended_dn = Convert::ASN1->new; + $asn_extended_dn->prepare( + q< ExtendedDn ::= SEQUENCE { + mode INTEGER + } + > + ); + + # only w2k3 accepts '1' and needs the ctl_val, w2k does not accept a ctl_val + my $ctl_extended_dn_val = $asn_extended_dn->encode( mode => $opt_display_extendeddn); + my $ctl_extended_dn = Net::LDAP::Control->new( + type => $ads_controls{'LDAP_SERVER_EXTENDED_DN_OID'}, + critical => 'true', + value => $opt_display_extendeddn ? $ctl_extended_dn_val : ""); + + # setup search options + my $search_opt = Convert::ASN1->new; + $search_opt->prepare( + q< searchopt ::= SEQUENCE { + flags INTEGER + } + > + ); + + my $tmp = $search_opt->encode( flags => $opt_search_opt); + my $ctl_search_opt = Net::LDAP::Control->new( + type => $ads_controls{'LDAP_SERVER_SEARCH_OPTIONS_OID'}, + critical => 'true', + value => $tmp); + + # setup notify control + my $ctl_notification = Net::LDAP::Control->new( + type => $ads_controls{'LDAP_SERVER_NOTIFICATION_OID'}, + critical => 'true'); + + + # setup paging control + $ctl_paged = Net::LDAP::Control->new( + type => $ads_controls{'LDAP_PAGED_RESULT_OID_STRING'}, + critical => 'true', + size => $opt_paging ? $opt_paging : 1000); + + # setup domscope control + my $ctl_domscope = Net::LDAP::Control->new( + type => $ads_controls{'LDAP_SERVER_DOMAIN_SCOPE_OID'}, + critical => 'true', + value => ""); + + if (defined($opt_paging) || $opt_dump_schema) { + push(@ctrls, $ctl_paged); + push(@ctrls_s, "LDAP_PAGED_RESULT_OID_STRING" ); + } + + if (defined($opt_display_extendeddn)) { + push(@ctrls, $ctl_extended_dn); + push(@ctrls_s, "LDAP_SERVER_EXTENDED_DN_OID"); + } + if ($opt_notify) { + push(@ctrls, $ctl_notification); + push(@ctrls_s, "LDAP_SERVER_NOTIFICATION_OID"); + } + + if ($opt_asq) { + push(@ctrls, $ctl_asq); + push(@ctrls_s, "LDAP_SERVER_ASQ_OID"); + } + + if ($opt_domain_scope) { + push(@ctrls, $ctl_domscope); + push(@ctrls_s, "LDAP_SERVER_DOMAIN_SCOPE_OID"); + } + + if ($opt_search_opt) { + push(@ctrls, $ctl_search_opt); + push(@ctrls_s, "LDAP_SERVER_SEARCH_OPTIONS_OID"); + } + + return @ctrls; +} + +sub display_value_generic ($$$) { + + my ($mod,$attr,$value) = @_; + return unless (defined($value) and defined($attr)); + + if ( ! $opt_display_raw && exists $attr_handler{$attr} ) { + $value = $attr_handler{$attr}($value,$mod); + write_ads_list($mod,$attr,$value); + return; + } + write_ads($mod,$attr,$value); +} + +sub display_attr_generic ($$$) { + + my ($mod,$entry,$attr) = @_; + return if (!$attr || !$entry); + + my $ref = $entry->get_value($attr, asref => 1); + my @values = @$ref; + + foreach my $value ( sort @values) { + display_value_generic($mod,$attr,$value); + } +} + +sub display_entry_generic ($) { + + my $entry = shift; + return if (!$entry); + + foreach my $attr ( sort $entry->attributes) { + display_attr_generic("\t",$entry,$attr); + } +} + +sub display_ldap_err ($) { + + my $msg = shift; + print_header(); + my ($package, $filename, $line, $subroutine) = caller(0); + + print "got error from ADS:\n"; + printf("%s(%d): ERROR (%s): %s\n", + $subroutine, $line, $msg->code, $msg->error); + +} + +sub process_result { + + my ($msg,$entry) = @_; + + if (!defined($msg)) { + return; + } + + if ($msg->code) { + display_ldap_err($msg); + exit 1; + } + + if (!defined($entry)) { + return; + } + + if ($entry->isa('Net::LDAP::Reference')) { + foreach my $ref ($entry->references) { + print "\ngot Reference: [$ref]\n"; + } + return; + } + + print "\nfound entry: ".$entry->dn."\n".("-" x 80)."\n"; + + display_entry_generic($entry); +} + +sub default_callback { + + my ($res,$obj) = @_; + + if (!$opt_notify && $res->code == LDAP_REFERRAL) { + return; + } + + if (!$opt_notify) { + return process_result($res,$obj); + } +} + +sub error_callback { + + my ($msg,$entry) = @_; + + if (!$msg) { + return; + } + + if ($msg->code) { + display_ldap_err($msg); + exit(1); + } + return; +} + +sub notify_callback { + + my ($msg, $obj) = @_; + + if (! defined($obj)) { + return; + } + + if ($obj->isa('Net::LDAP::Reference')) { + foreach my $ref ($obj->references) { + print "\ngot Reference: [$ref]\n"; + } + return; + } + + while (1) { + + my $async_entry = $async_search->pop_entry; + + if (!$async_entry->dn) { + print "very weird. entry has no dn\n"; + next; + } + + printf("\ngot changenotify for dn: [%s]\n%s\n", $async_entry->dn, ("-" x 80)); + + my $new_usn = $async_entry->get_value('uSNChanged'); + if (!$new_usn) { + die "odd, no usnChanged attribute???"; + } + if (!$usn || $new_usn > $usn) { + $usn = $new_usn; + if ($opt_notify_nodiffs) { + display_entry_generic($async_entry); + } else { + display_result_diff($async_entry); + } + } + store_result($async_entry); + } +} + +sub do_bind($$) { + + my $async_ldap_hd = shift || return undef; + my $sasl_bind = shift; + + if ($sasl_bind) { + if (!$works_sasl) { + print "this version of Net::LDAP does not have proper SASL support.\n"; + print "Need at least perl-ldap V. $pref_version\n"; + } + $sasl_hd = get_sasl_hd(); + if (!$sasl_hd) { + print "failed to create SASL handle\n"; + return -1; + } + $mesg = $async_ldap_hd->bind( + sasl => $sasl_hd, + callback => \&error_callback + ) || die "doesnt work"; + } else { + $sasl_mech = ""; + $mesg = $async_ldap_hd->bind( + $binddn, + password => $password, + callback => $opt_fastbind ? undef : \&error_callback + ) || die "doesnt work"; + }; + if ($mesg->code) { + display_ldap_err($mesg) if (!$opt_fastbind); + return -1; + } + return 0; +} + +sub do_fast_bind() { + + do_unbind(); + + my $hd = get_ldap_hd($server,1); + + my $mesg = $hd->extension( + name => $ads_extensions{'LDAP_SERVER_FAST_BIND_OID'}); + + if ($mesg->code) { + display_ldap_err($mesg); + return -1; + } + + my $ret = do_bind($hd, undef); + $hd->unbind; + + printf("bind using 'LDAP_SERVER_FAST_BIND_OID' %s\n", + $ret == 0 ? "succeeded" : "failed"); + + return $ret; +} + +sub do_unbind() { + if ($async_ldap_hd) { + $async_ldap_hd->unbind; + } + if ($sync_ldap_hd) { + $sync_ldap_hd->unbind; + } +} + +############################################################################### + +sub main () { + + if ($opt_fastbind) { + + if (check_exts($server,$dse,"LDAP_SERVER_FAST_BIND_OID") == -1) { + print "LDAP_SERVER_FAST_BIND_OID not supported by this server\n"; + exit 1; + } + + # fast bind can only bind, not search + exit do_fast_bind(); + } + + $filter = construct_filter($query); + @attrs = construct_attrs(@attrs); + @ctrls = gen_controls(); + + if (check_ctrls($server,$dse,@ctrls) == -1) { + print "not all required LDAP Controls are supported by this server\n"; + exit 1; + } + + if ($opt_dump_rootdse) { + print "Dumping Root-DSE:\n"; + display_entry_generic($dse); + exit 0; + } + + if ($opt_dump_wknguid) { + dump_wknguid(); + exit 0; + } + + if (do_bind($async_ldap_hd, $sasl_bind) == -1) { + exit 1; + } + + print_header(); + + if ($opt_dump_schema) { + print "Dumping Schema:\n"; +# my $ads_schema = $async_ldap_hd->schema; +# $ads_schema->dump; +# exit 0; + } + + while (1) { + + $async_search = $async_ldap_hd->search( + base => $base, + filter => $filter, + attrs => [ @attrs ], + control => [ @ctrls ], + callback => \&default_callback, + scope => $scope, + ) || die "cannot search"; + + if (!$opt_notify && ($async_search->code == LDAP_REFERRAL)) { + foreach my $ref ($async_search->referrals) { + print "\ngot Referral: [$ref]\n"; + my ($prot, $host, $base) = split(/\/+/, $ref); + $async_ldap_hd->unbind(); + $async_ldap_hd = get_ldap_hd($host, 1); + if (do_bind($async_ldap_hd, $sasl_bind) == -1) { + $async_ldap_hd->unbind(); + next; + } + print "\nsuccessful rebind to: [$ref]\n"; + last; + } + next; # repeat the query + } + + if ($opt_notify) { + + print "Base [$base] is registered now for change-notify\n"; + print "\nWaiting for change-notify...\n"; + + my $sync_ldap_hd = get_ldap_hd($server,0); + if (do_bind($sync_ldap_hd, $sasl_bind) == -1) { + exit 2; + } + + my $sync_search = $sync_ldap_hd->search( + base => $base, + filter => $filter, + attrs => [ @attrs ], + callback => \¬ify_callback, + scope => $scope, + ) || die "cannot search"; + + } + + $total_entry_count += $async_search->count; + ++$page_count; + print "-" x 80 . "\n"; + printf("Got %d Entries in Page %d \n\n", + $async_search->count, $page_count); + my ($resp) = $async_search->control( + $ads_controls{'LDAP_PAGED_RESULT_OID_STRING'} ) or last; + last unless ref $resp && $ctl_paged->cookie($resp->cookie); + } + + if ($async_search->entries == 0) { + print "No entries found with filter $filter\n"; + } else { + print "Got $total_entry_count Entries in $page_count Pages\n" if ($opt_paging); + } + + do_unbind() +} + +main(); + +exit 0; diff --git a/examples/misc/check_multiple_LDAP_entries.pl b/examples/misc/check_multiple_LDAP_entries.pl new file mode 100755 index 0000000000..00c197ace4 --- /dev/null +++ b/examples/misc/check_multiple_LDAP_entries.pl @@ -0,0 +1,201 @@ +#!/usr/bin/perl -w +# Guenther Deschner <gd@samba.org> +# +# check for multiple LDAP entries + +use strict; + +use Net::LDAP; +use Getopt::Std; + +my %opts; + +if (!@ARGV) { + print "usage: $0 -h host -b base -D admindn -w password [-l]\n"; + print "\tperforms checks for multiple sid, uid and gid-entries on your LDAP server\n"; + print "\t-l adds additional checks against the local /etc/passwd and /etc/group file\n"; + exit 1; +} + +getopts('b:h:D:w:l', \%opts); + +my $host = $opts{h} || "localhost"; +my $suffix = $opts{b} || die "please set base with -b"; +my $binddn = $opts{D} || die "please set basedn with -D"; +my $bindpw = $opts{w} || die "please set password with -w"; +my $check_local_files = $opts{l} || 0; + +######################## + + +my ($ldap, $res); +my (%passwd_h, %group_h); +my $bad_uids = 0; +my $bad_gids = 0; +my $bad_sids = 0; +my $ret = 0; + +if ($check_local_files) { + my @uids = `cut -d ':' -f 3 /etc/passwd`; + my @gids = `cut -d ':' -f 3 /etc/group`; + + foreach my $uid (@uids) { + chomp($uid); + $passwd_h{$uid} = $uid; + } + + foreach my $gid (@gids) { + chomp($gid); + $group_h{$gid} = $gid; + } +} + +######## +# bind # +######## + +$ldap = Net::LDAP->new($host, version => '3'); + +$res = $ldap->bind( $binddn, password => $bindpw); +$res->code && die "failed to bind: ", $res->error; + + + +########################### +# check for double sids # +########################### + +print "\ntesting for multiple sambaSids\n"; + +$res = $ldap->search( + base => $suffix, + filter => "(objectclass=sambaSamAccount)"); + +$res->code && die "failed to search: ", $res->error; + +foreach my $entry ($res->all_entries) { + + my $sid = $entry->get_value('sambaSid'); + + my $local_res = $ldap->search( + base => $suffix, + filter => "(&(objectclass=sambaSamAccount)(sambaSid=$sid))"); + + $local_res->code && die "failed to search: ", $local_res->error; + if ($local_res->count > 1) { + print "A SambaSamAccount with sambaSid [$sid] must exactly exist once\n"; + print "You have ", $local_res->count, " entries:\n"; + foreach my $loc_entry ($local_res->all_entries) { + printf "\t%s\n", $loc_entry->dn; + } + ++$bad_sids; + } +} + +if ($bad_sids) { + $ret = -1; + print "You have $bad_sids bad sambaSids in your system. You might need to repair them\n"; +} else { + print "No multiple sambaSids found in your system\n"; +} + +print "-" x 80, "\n"; + +########################### +# check for double groups # +########################### + +print "\ntesting for multiple gidNumbers\n"; + +$res = $ldap->search( + base => $suffix, + filter => "(objectclass=posixGroup)"); + +$res->code && die "failed to search: ", $res->error; + +foreach my $entry ($res->all_entries) { + + my $gid = $entry->get_value('gidNumber'); + my $dn = $entry->dn; + + my $local_res = $ldap->search( + base => $suffix, + filter => "(&(objectclass=posixGroup)(gidNumber=$gid))"); + + $local_res->code && die "failed to search: ", $local_res->error; + if ($local_res->count > 1) { + print "A PosixGroup with gidNumber [$gid] must exactly exist once\n"; + print "You have ", $local_res->count, " entries:\n"; + foreach my $loc_entry ($local_res->all_entries) { + printf "\t%s\n", $loc_entry->dn; + } + ++$bad_gids; + next; + } + + if ($check_local_files && exists $group_h{$gid}) { + print "Warning: There is a group in /etc/group that has gidNumber [$gid] as well\n"; + print "This entry may conflict with $dn\n"; + ++$bad_gids; + } +} + +if ($bad_gids) { + $ret = -1; + print "You have $bad_gids bad gidNumbers in your system. You might need to repair them\n"; +} else { + print "No multiple gidNumbers found in your system\n"; +} + +print "-" x 80, "\n"; + + +########################### +# check for double users # +########################### + +print "\ntesting for multiple uidNumbers\n"; + +$res = $ldap->search( + base => $suffix, + filter => "(objectclass=posixAccount)"); + +$res->code && die "failed to search: ", $res->error; + + +foreach my $entry ($res->all_entries) { + + my $uid = $entry->get_value('uidNumber'); + my $dn = $entry->dn; + + my $local_res = $ldap->search( + base => $suffix, + filter => "(&(objectclass=posixAccount)(uidNumber=$uid))"); + + $local_res->code && die "failed to search: ", $local_res->error; + if ($local_res->count > 1) { + print "A PosixAccount with uidNumber [$uid] must exactly exist once\n"; + print "You have ", $local_res->count, " entries:\n"; + foreach my $loc_entry ($local_res->all_entries) { + printf "\t%s\n", $loc_entry->dn; + } + ++$bad_uids; + next; + } + if ($check_local_files && exists $passwd_h{$uid}) { + print "Warning: There is a user in /etc/passwd that has uidNumber [$uid] as well\n"; + print "This entry may conflict with $dn\n"; + ++$bad_uids; + } +} + +if ($bad_uids) { + $ret = -1; + print "You have $bad_uids bad uidNumbers in your system. You might need to repair them\n"; +} else { + print "No multiple uidNumbers found in your system\n"; +} + +$ldap->unbind; + +exit $ret; diff --git a/examples/misc/cldap.pl b/examples/misc/cldap.pl new file mode 100755 index 0000000000..c33fdedfbf --- /dev/null +++ b/examples/misc/cldap.pl @@ -0,0 +1,491 @@ +#!/usr/bin/perl -w + +# Copyright (C) Guenther Deschner <gd@samba.org> 2006 + +use strict; +use IO::Socket; +use Convert::ASN1 qw(:debug); +use Getopt::Long; + +# TODO: timeout handling, user CLDAP query + +################################## + +my $server = ""; +my $domain = ""; +my $host = ""; + +################################## + +my ( + $opt_debug, + $opt_domain, + $opt_help, + $opt_host, + $opt_server, +); + +my %cldap_flags = ( + ADS_PDC => 0x00000001, # DC is PDC + ADS_GC => 0x00000004, # DC is a GC of forest + ADS_LDAP => 0x00000008, # DC is an LDAP server + ADS_DS => 0x00000010, # DC supports DS + ADS_KDC => 0x00000020, # DC is running KDC + ADS_TIMESERV => 0x00000040, # DC is running time services + ADS_CLOSEST => 0x00000080, # DC is closest to client + ADS_WRITABLE => 0x00000100, # DC has writable DS + ADS_GOOD_TIMESERV => 0x00000200, # DC has hardware clock (and running time) + ADS_NDNC => 0x00000400, # DomainName is non-domain NC serviced by LDAP server +); + +my %cldap_samlogon_types = ( + SAMLOGON_AD_UNK_R => 23, + SAMLOGON_AD_R => 25, +); + +my $MAX_DNS_LABEL = 255 + 1; + +my %cldap_netlogon_reply = ( + type => 0, + flags => 0x0, + guid => 0, + forest => undef, + domain => undef, + hostname => undef, + netbios_domain => undef, + netbios_hostname => undef, + unk => undef, + user_name => undef, + server_site_name => undef, + client_site_name => undef, + version => 0, + lmnt_token => 0x0, + lm20_token => 0x0, +); + +sub usage { + print "usage: $0 [--domain|-d domain] [--help] [--host|-h host] [--server|-s server]\n\n"; +} + +sub connect_cldap ($) { + + my $server = shift || return undef; + + return IO::Socket::INET->new( + PeerAddr => $server, + PeerPort => 389, + Proto => 'udp', + Type => SOCK_DGRAM, + Timeout => 10, + ); +} + +sub send_cldap_netlogon ($$$$) { + + my ($sock, $domain, $host, $ntver) = @_; + + my $asn_cldap_req = Convert::ASN1->new; + + $asn_cldap_req->prepare(q< + + SEQUENCE { + msgid INTEGER, + [APPLICATION 3] SEQUENCE { + basedn OCTET STRING, + scope ENUMERATED, + dereference ENUMERATED, + sizelimit INTEGER, + timelimit INTEGER, + attronly BOOLEAN, + [CONTEXT 0] SEQUENCE { + [CONTEXT 3] SEQUENCE { + dnsdom_attr OCTET STRING, + dnsdom_val OCTET STRING + } + [CONTEXT 3] SEQUENCE { + host_attr OCTET STRING, + host_val OCTET STRING + } + [CONTEXT 3] SEQUENCE { + ntver_attr OCTET STRING, + ntver_val OCTET STRING + } + } + SEQUENCE { + netlogon OCTET STRING + } + } + } + >); + + my $pdu_req = $asn_cldap_req->encode( + msgid => 0, + basedn => "", + scope => 0, + dereference => 0, + sizelimit => 0, + timelimit => 0, + attronly => 0, + dnsdom_attr => $domain ? 'DnsDomain' : "", + dnsdom_val => $domain ? $domain : "", + host_attr => 'Host', + host_val => $host, + ntver_attr => 'NtVer', + ntver_val => $ntver, + netlogon => 'NetLogon', + ) || die "failed to encode pdu: $@"; + + if ($opt_debug) { + print"------------\n"; + asn_dump($pdu_req); + print"------------\n"; + } + + return $sock->send($pdu_req) || die "no send: $@"; +} + +# from source/libads/cldap.c : +# +#/* +# These seem to be strings as described in RFC1035 4.1.4 and can be: +# +# - a sequence of labels ending in a zero octet +# - a pointer +# - a sequence of labels ending with a pointer +# +# A label is a byte where the first two bits must be zero and the remaining +# bits represent the length of the label followed by the label itself. +# Therefore, the length of a label is at max 64 bytes. Under RFC1035, a +# sequence of labels cannot exceed 255 bytes. +# +# A pointer consists of a 14 bit offset from the beginning of the data. +# +# struct ptr { +# unsigned ident:2; // must be 11 +# unsigned offset:14; // from the beginning of data +# }; +# +# This is used as a method to compress the packet by eliminated duplicate +# domain components. Since a UDP packet should probably be < 512 bytes and a +# DNS name can be up to 255 bytes, this actually makes a lot of sense. +#*/ + +sub pull_netlogon_string (\$$$) { + + my ($ret, $ptr, $str) = @_; + + my $pos = $ptr; + + my $followed_ptr = 0; + my $ret_len = 0; + + my $retp = pack("x$MAX_DNS_LABEL"); + + do { + + $ptr = unpack("c", substr($str, $pos, 1)); + $pos++; + + if (($ptr & 0xc0) == 0xc0) { + + my $len; + + if (!$followed_ptr) { + $ret_len += 2; + $followed_ptr = 1; + } + + my $tmp0 = $ptr; #unpack("c", substr($str, $pos-1, 1)); + my $tmp1 = unpack("c", substr($str, $pos, 1)); + + if ($opt_debug) { + printf("tmp0: 0x%x\n", $tmp0); + printf("tmp1: 0x%x\n", $tmp1); + } + + $len = (($tmp0 & 0x3f) << 8) | $tmp1; + $ptr = unpack("c", substr($str, $len, 1)); + $pos = $len; + + } elsif ($ptr) { + + my $len = scalar $ptr; + + if ($len + 1 > $MAX_DNS_LABEL) { + warn("invalid string size: %d", $len + 1); + return 0; + } + + $ptr = unpack("a*", substr($str, $pos, $len)); + + $retp = sprintf("%s%s\.", $retp, $ptr); + + $pos += $len; + if (!$followed_ptr) { + $ret_len += $len + 1; + } + } + + } while ($ptr); + + $retp =~ s/\.$//; #ugly hack... + + $$ret = $retp; + + return $followed_ptr ? $ret_len : $ret_len + 1; +} + +sub dump_cldap_flags ($) { + + my $flags = shift || return; + printf("Flags:\n". + "\tIs a PDC: %s\n". + "\tIs a GC of the forest: %s\n". + "\tIs an LDAP server: %s\n". + "\tSupports DS: %s\n". + "\tIs running a KDC: %s\n". + "\tIs running time services: %s\n". + "\tIs the closest DC: %s\n". + "\tIs writable: %s\n". + "\tHas a hardware clock: %s\n". + "\tIs a non-domain NC serviced by LDAP server: %s\n", + ($flags & $cldap_flags{ADS_PDC}) ? "yes" : "no", + ($flags & $cldap_flags{ADS_GC}) ? "yes" : "no", + ($flags & $cldap_flags{ADS_LDAP}) ? "yes" : "no", + ($flags & $cldap_flags{ADS_DS}) ? "yes" : "no", + ($flags & $cldap_flags{ADS_KDC}) ? "yes" : "no", + ($flags & $cldap_flags{ADS_TIMESERV}) ? "yes" : "no", + ($flags & $cldap_flags{ADS_CLOSEST}) ? "yes" : "no", + ($flags & $cldap_flags{ADS_WRITABLE}) ? "yes" : "no", + ($flags & $cldap_flags{ADS_GOOD_TIMESERV}) ? "yes" : "no", + ($flags & $cldap_flags{ADS_NDNC}) ? "yes" : "no"); +} + +sub guid_to_string ($) { + + my $guid = shift || return undef; + if ((my $len = length $guid) != 16) { + printf("invalid length: %d\n", $len); + return undef; + } + my $string = sprintf "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + unpack("I", $guid), + unpack("S", substr($guid, 4, 2)), + unpack("S", substr($guid, 6, 2)), + unpack("C", substr($guid, 8, 1)), + unpack("C", substr($guid, 9, 1)), + unpack("C", substr($guid, 10, 1)), + unpack("C", substr($guid, 11, 1)), + unpack("C", substr($guid, 12, 1)), + unpack("C", substr($guid, 13, 1)), + unpack("C", substr($guid, 14, 1)), + unpack("C", substr($guid, 15, 1)); + return lc($string); +} + +sub recv_cldap_netlogon ($\$) { + + my ($sock, $return_string) = @_; + my ($ret, $pdu_out); + + $ret = $sock->recv($pdu_out, 8192) || die "failed to read from socket: $@"; + #$ret = sysread($sock, $pdu_out, 8192); + + if ($opt_debug) { + print"------------\n"; + asn_dump($pdu_out); + print"------------\n"; + } + + my $asn_cldap_rep = Convert::ASN1->new; + my $asn_cldap_rep_fail = Convert::ASN1->new; + + $asn_cldap_rep->prepare(q< + SEQUENCE { + msgid INTEGER, + [APPLICATION 4] SEQUENCE { + dn OCTET STRING, + SEQUENCE { + SEQUENCE { + attr OCTET STRING, + SET { + val OCTET STRING + } + } + } + } + } + SEQUENCE { + msgid2 INTEGER, + [APPLICATION 5] SEQUENCE { + error_code ENUMERATED, + matched_dn OCTET STRING, + error_message OCTET STRING + } + } + >); + + $asn_cldap_rep_fail->prepare(q< + SEQUENCE { + msgid2 INTEGER, + [APPLICATION 5] SEQUENCE { + error_code ENUMERATED, + matched_dn OCTET STRING, + error_message OCTET STRING + } + } + >); + + my $asn1_rep = $asn_cldap_rep->decode($pdu_out) || + $asn_cldap_rep_fail->decode($pdu_out) || + die "failed to decode pdu: $@"; + + if ($asn1_rep->{'error_code'} == 0) { + $$return_string = $asn1_rep->{'val'}; + } + + return $ret; +} + +sub parse_cldap_reply ($) { + + my $str = shift || return undef; + my %hash; + my $p = 0; + + $hash{type} = unpack("L", substr($str, $p, 4)); $p += 4; + $hash{flags} = unpack("L", substr($str, $p, 4)); $p += 4; + $hash{guid} = unpack("a16", substr($str, $p, 16)); $p += 16; + + $p += pull_netlogon_string($hash{forest}, $p, $str); + $p += pull_netlogon_string($hash{domain}, $p, $str); + $p += pull_netlogon_string($hash{hostname}, $p, $str); + $p += pull_netlogon_string($hash{netbios_domain}, $p, $str); + $p += pull_netlogon_string($hash{netbios_hostname}, $p, $str); + $p += pull_netlogon_string($hash{unk}, $p, $str); + + if ($hash{type} == $cldap_samlogon_types{SAMLOGON_AD_R}) { + $p += pull_netlogon_string($hash{user_name}, $p, $str); + } else { + $hash{user_name} = ""; + } + + $p += pull_netlogon_string($hash{server_site_name}, $p, $str); + $p += pull_netlogon_string($hash{client_site_name}, $p, $str); + + $hash{version} = unpack("L", substr($str, $p, 4)); $p += 4; + $hash{lmnt_token} = unpack("S", substr($str, $p, 2)); $p += 2; + $hash{lm20_token} = unpack("S", substr($str, $p, 2)); $p += 2; + + return %hash; +} + +sub display_cldap_reply { + + my $server = shift; + my (%hash) = @_; + + my ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($server); + + printf("Information for Domain Controller: %s\n\n", $name); + + printf("Response Type: "); + if ($hash{type} == $cldap_samlogon_types{SAMLOGON_AD_R}) { + printf("SAMLOGON_USER\n"); + } elsif ($hash{type} == $cldap_samlogon_types{SAMLOGON_AD_UNK_R}) { + printf("SAMLOGON\n"); + } else { + printf("unknown type 0x%x, please report\n", $hash{type}); + } + + # guid + printf("GUID: %s\n", guid_to_string($hash{guid})); + + # flags + dump_cldap_flags($hash{flags}); + + # strings + printf("Forest:\t\t\t%s\n", $hash{forest}); + printf("Domain:\t\t\t%s\n", $hash{domain}); + printf("Domain Controller:\t%s\n", $hash{hostname}); + + printf("Pre-Win2k Domain:\t%s\n", $hash{netbios_domain}); + printf("Pre-Win2k Hostname:\t%s\n", $hash{netbios_hostname}); + + if ($hash{unk}) { + printf("Unk:\t\t\t%s\n", $hash{unk}); + } + if ($hash{user_name}) { + printf("User name:\t%s\n", $hash{user_name}); + } + + printf("Server Site Name:\t%s\n", $hash{server_site_name}); + printf("Client Site Name:\t%s\n", $hash{client_site_name}); + + # some more int + printf("NT Version:\t\t%d\n", $hash{version}); + printf("LMNT Token:\t\t%.2x\n", $hash{lmnt_token}); + printf("LM20 Token:\t\t%.2x\n", $hash{lm20_token}); +} + +sub main() { + + my ($ret, $sock, $reply); + + GetOptions( + 'debug' => \$opt_debug, + 'domain|d=s' => \$opt_domain, + 'help' => \$opt_help, + 'host|h=s' => \$opt_host, + 'server|s=s' => \$opt_server, + ); + + $server = $server || $opt_server; + $domain = $domain || $opt_domain || undef; + $host = $host || $opt_host; + if (!$host) { + $host = `/bin/hostname`; + chomp($host); + } + + if (!$server || !$host || $opt_help) { + usage(); + exit 1; + } + + my $ntver = sprintf("%c%c%c%c", 6,0,0,0); + + $sock = connect_cldap($server); + if (!$sock) { + die("could not connect to $server"); + } + + $ret = send_cldap_netlogon($sock, $domain, $host, $ntver); + if (!$ret) { + close($sock); + die("failed to send CLDAP request to $server"); + } + + $ret = recv_cldap_netlogon($sock, $reply); + if (!$ret) { + close($sock); + die("failed to receive CLDAP reply from $server"); + } + close($sock); + + if (!$reply) { + printf("no 'NetLogon' attribute received\n"); + exit 0; + } + + %cldap_netlogon_reply = parse_cldap_reply($reply); + if (!%cldap_netlogon_reply) { + die("failed to parse CLDAP reply from $server"); + } + + display_cldap_reply($server, %cldap_netlogon_reply); + + exit 0; +} + +main(); diff --git a/examples/misc/extra_smbstatus b/examples/misc/extra_smbstatus new file mode 100644 index 0000000000..7f77d07d00 --- /dev/null +++ b/examples/misc/extra_smbstatus @@ -0,0 +1,50 @@ +Here's something that Paul Blackman sent me that may be useful: + +------------------- +I created this script to do a few things that smbstatus doesn't at the +moment. Perhaps you might want to include these. Sorry I haven't +added things at source level, script was quick&easy. + +******* +#!/bin/csh +if ($1 == "-p") then + smbstatus -p |sort -u +else if ($1 == "-c") then + echo There are `smbstatus -p |sort -u |grep -n -v z |grep -c :` unique smbd processes running. + else if ($1 == "-l") then + echo `date '+ %d/%m/%y %H:%M:%S'` `smbstatus -p |sort -u |grep -n -v z |grep -c :` >>$2 +else if ($1 == "-cs") then + echo There are `smbstatus |awk '$1==share {n++;} END {print n}' share=$2` concurrent connections to share: $2 +else if ($1 == "-csl") then + echo `date '+ %d/%m/%y %H:%M:%S'` `smbstatus |awk '$1==share {n++;} END {print n}' share=$2` >>$3 +else + echo "'smbstat -c' ==> Count unique smbd processes." + echo "'smbstat -p' ==> List unique smbd processes." + echo "'smbstat -l logfile' ==> Append a log entry for the number of" + echo " concurrent and unique processes to logfile." + echo "'smbstat -cs sharename'" + echo " ==> Count processes connected to sharename (assumed unique)" + echo "'smbstat -csl sharename logfile'" + echo " ==> Append a log entry for the number of concurrent" + echo " processes connected to sharename (assumed unique)" +endif +****** + +Run this script from cron eg. + +0,5,10,15,20,25,30,35,40,50,55 * * * * /usr/local/samba/bin/smbstat -l /usr/local/samba/var/smbdcount.log + +and you get a good idea of usage over time. + +Cheers, +~^ MIME OK ^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~ + o | Paul Blackman ictinus@lake.canberra.edu.au + o | Co-operative Research ------------------------ + o _ | Centre For Freshwater Ecology. Ph. (Aus) 06 2012518 + -- (") o | University of Canberra, Australia. Fax. " 06 2015038 + \_|_-- |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | "Spend a little love and get high" + _/ \_ | - Lenny Kravitz +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~ SAMBA Web Pages: http://samba.org/samba/ ~~~~~~~~~~~~~~ + diff --git a/examples/misc/swat.pl b/examples/misc/swat.pl new file mode 100644 index 0000000000..f6414b6349 --- /dev/null +++ b/examples/misc/swat.pl @@ -0,0 +1,122 @@ +#! /usr/bin/perl5 +## +## This is a simple script written by Herb Lewis @ SGI <herb@samba.org> +## for reporting which parameters are supported by loadparm.c but +## not by SWAT I just thought it looked fun and might be of interest to others +## --jerry@samba.org +## +## Here is a little info on the usage and output format so you don't have +## to dig through the code to understand what is printed. +## +## Useage: swat.pl [path_to_loadparm.c] +## +## The output consists of 4 columns of information +## Option Name, Global Page, Share Page, Printer Page +## The section separaters will also be printed (preceded by 16 *) to show +## which options are grouped in the various sections. +## +## If the option name is preceded by an * it means this is a deprecated option. +## If the option name is preceded by 5 spaces it means this is an alias for the +## previous option. +## +## Under the Global Page, Share Page, and Printer Page columns there will be +## one of 3 entries, BASIC, ADVANCED, or no. "BASIC" indicates this option will +## show in the Basic View of that page in SWAT. "ADVANCED" indicates this +## option will show in the Advanced View of that page in SWAT. "No" indicates +## that this option is not available on that page in SWAT. +## +## Under the Global Page column, if an entry begins with an * it indicates that +## this is actually specified in Samba as a "service parameter" not a "global +## parameter" but you can set a default value for this on the Global Page in +## SWAT. +## +## --herb@samba.org + +$lastone = "nothing"; + +if (@ARGV[0]) { + $filename = @ARGV[0]; +} else { + $filename = "/usr3/samba20/samba/source/param/loadparm.c"; +} + +open (INFILE,$filename) || die "unable to open $filename\n"; +while (not eof(INFILE)) +{ + $_ = <INFILE>; + last if ( /^static struct parm_struct parm_table/) ; +} +print "Option Name Global Page Share Page Printer Page\n"; +print "---------------------------------------------------------------------"; +while (not eof(INFILE)) +{ + $_ = <INFILE>; + last if (/};/); + @fields = split(/,/,$_); + next if not ($fields[0] =~ /^.*{"/); + $fields[0] =~ s/.*{"//; + $fields[0] =~ s/"//; + if ($fields[3] eq $lastone) { + print " $fields[0]\n"; + next; + } + $lastone = $fields[3]; + $fields[2] =~ s/^\s+//; + $fields[2] =~ s/\s+$//; + $fields[2] =~ s/}.*$//; + $fields[6] =~ s/^\s+//; + $fields[6] =~ s/\s+$//; + $fields[6] =~ s/}.*$//; + if ($fields[2] =~ /P_SEPARATOR/) { + print "\n****************$fields[0]\n"; + next; + } + else { + if ($fields[6] =~ /FLAG_DEPRECATED/) { + print "*$fields[0]".' 'x(31-length($fields[0])); + } + else { + print "$fields[0]".' 'x(32-length($fields[0])); + } + } + if (($fields[2] =~ /P_GLOBAL/) || ($fields[6] =~ /FLAG_GLOBAL/)) { + if ($fields[6] =~ /FLAG_GLOBAL/) { + print "*"; + } + else { + print " "; + } + if ($fields[6] =~ /FLAG_BASIC/) { + print "BASIC "; + } + else { + print "ADVANCED "; + } + } + else { + print " no "; + } + if ($fields[6] =~ /FLAG_SHARE/) { + if ($fields[6] =~ /FLAG_BASIC/) { + print "BASIC "; + } + else { + print "ADVANCED "; + } + } + else { + print "no "; + } + if ($fields[6] =~ /FLAG_PRINT/) { + if ($fields[6] =~ /FLAG_BASIC/) { + print "BASIC"; + } + else { + print "ADVANCED"; + } + } + else { + print "no"; + } + print "\n"; +} diff --git a/examples/misc/wall.perl b/examples/misc/wall.perl new file mode 100644 index 0000000000..9303658ce1 --- /dev/null +++ b/examples/misc/wall.perl @@ -0,0 +1,69 @@ +#!/usr/local/bin/perl +# +#@(#) smb-wall.pl Description: +#@(#) A perl script which allows you to announce whatever you choose to +#@(#) every PC client currently connected to a Samba Server... +#@(#) ...using "smbclient -M" message to winpopup service. +#@(#) Default usage is to message every connected PC. +#@(#) Alternate usage is to message every pc on the argument list. +#@(#) Hacked up by Keith Farrar <farrar@parc.xerox.com> +# +# Cleanup and corrections by +# Michal Jaegermann <michal@ellpspace.math.ualberta.ca> +# Message to send can be now also fed (quietly) from stdin; a pipe will do. +#============================================================================= + +$smbstatus = "/usr/local/bin/smbstatus"; +$smbshout = "/usr/local/bin/smbclient -M"; + +if (@ARGV) { + @clients = @ARGV; + undef @ARGV; +} +else { # no clients specified explicitly + open(PCLIST, "$smbstatus |") || die "$smbstatus failed!.\n$!\n"; + while(<PCLIST>) { + last if /^Locked files:/; + split(' ', $_, 6); + # do not accept this line if less then six fields + next unless $_[5]; + # if you have A LOT of clients you may speed things up by + # checking pid - no need to look further if this pid was already + # seen; left as an exercise :-) + $client = $_[4]; + next unless $client =~ /^\w+\./; # expect 'dot' in a client name + next if grep($_ eq $client, @clients); # we want this name once + push(@clients, $client); + } + close(PCLIST); +} + +if (-t) { + print <<'EOT'; + +Enter message for Samba clients of this host +(terminated with single '.' or end of file): +EOT + + while (<>) { + last if /^\.$/; + push(@message, $_); + } +} +else { # keep quiet and read message from stdin + @message = <>; +} + +foreach(@clients) { +## print "To $_:\n"; + if (open(SENDMSG,"|$smbshout $_")) { + print SENDMSG @message; + close(SENDMSG); + } + else { + warn "Cannot notify $_ with $smbshout:\n$!\n"; + } +} + +exit 0; + diff --git a/examples/nss/nss_winbind.c b/examples/nss/nss_winbind.c new file mode 100644 index 0000000000..968cc7addd --- /dev/null +++ b/examples/nss/nss_winbind.c @@ -0,0 +1,422 @@ +/* + nss sample code for extended winbindd functionality + + Copyright (C) Andrew Tridgell (tridge@samba.org) + + you are free to use this code in any way you see fit, including + without restriction, using this code in your own products. You do + not need to give any attribution. +*/ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <nss.h> +#include <dlfcn.h> +#include <errno.h> +#include <string.h> +#include <sys/types.h> + +#include "nss_winbind.h" + +/* + find a function in the nss library +*/ +static void *find_fn(struct nss_state *nss, const char *name) +{ + void *res; + char *s = NULL; + + asprintf(&s, "_nss_%s_%s", nss->nss_name, name); + if (!s) { + errno = ENOMEM; + return NULL; + } + res = dlsym(nss->dl_handle, s); + free(s); + if (!res) { + errno = ENOENT; + return NULL; + } + return res; +} + +/* + establish a link to the nss library + Return 0 on success and -1 on error +*/ +int nss_open(struct nss_state *nss, const char *nss_path) +{ + char *p; + p = strrchr(nss_path, '_'); + if (!p) { + errno = EINVAL; + return -1; + } + + nss->nss_name = strdup(p+1); + p = strchr(nss->nss_name, '.'); + if (p) *p = 0; + + nss->dl_handle = dlopen(nss_path, RTLD_LAZY); + if (!nss->dl_handle) { + free(nss->nss_name); + return -1; + } + + return 0; +} + +/* + close and cleanup a nss state +*/ +void nss_close(struct nss_state *nss) +{ + free(nss->nss_name); + dlclose(nss->dl_handle); +} + +/* + make a getpwnam call. + Return 0 on success and -1 on error +*/ +int nss_getpwent(struct nss_state *nss, struct passwd *pwd) +{ + enum nss_status (*_nss_getpwent_r)(struct passwd *, char *, + size_t , int *); + enum nss_status status; + int nss_errno = 0; + + _nss_getpwent_r = find_fn(nss, "getpwent_r"); + + if (!_nss_getpwent_r) { + return -1; + } + + status = _nss_getpwent_r(pwd, nss->pwnam_buf, sizeof(nss->pwnam_buf), + &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + return 0; +} + +/* + make a setpwent call. + Return 0 on success and -1 on error +*/ +int nss_setpwent(struct nss_state *nss) +{ + enum nss_status (*_nss_setpwent)(void) = find_fn(nss, "setpwent"); + enum nss_status status; + if (!_nss_setpwent) { + return -1; + } + status = _nss_setpwent(); + if (status != NSS_STATUS_SUCCESS) { + errno = EINVAL; + return -1; + } + return 0; +} + +/* + make a endpwent call. + Return 0 on success and -1 on error +*/ +int nss_endpwent(struct nss_state *nss) +{ + enum nss_status (*_nss_endpwent)(void) = find_fn(nss, "endpwent"); + enum nss_status status; + if (!_nss_endpwent) { + return -1; + } + status = _nss_endpwent(); + if (status != NSS_STATUS_SUCCESS) { + errno = EINVAL; + return -1; + } + return 0; +} + + +/* + convert a name to a SID + caller frees + Return 0 on success and -1 on error +*/ +int nss_nametosid(struct nss_state *nss, const char *name, char **sid) +{ + enum nss_status (*_nss_nametosid)(const char *, char **, char *, + size_t, int *); + enum nss_status status; + int nss_errno = 0; + char buf[200]; + + _nss_nametosid = find_fn(nss, "nametosid"); + + if (!_nss_nametosid) { + return -1; + } + + status = _nss_nametosid(name, sid, buf, sizeof(buf), &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + *sid = strdup(*sid); + + return 0; +} + +/* + convert a SID to a name + caller frees + Return 0 on success and -1 on error +*/ +int nss_sidtoname(struct nss_state *nss, const char *sid, char **name) +{ + enum nss_status (*_nss_sidtoname)(const char *, char **, char *, + size_t, int *); + enum nss_status status; + int nss_errno = 0; + char buf[200]; + + _nss_sidtoname = find_fn(nss, "sidtoname"); + + if (!_nss_sidtoname) { + return -1; + } + + status = _nss_sidtoname(sid, name, buf, sizeof(buf), &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + *name = strdup(*name); + + return 0; +} + +/* + return a list of group SIDs for a user SID + the returned list is NULL terminated + Return 0 on success and -1 on error +*/ +int nss_getusersids(struct nss_state *nss, const char *user_sid, char ***sids) +{ + enum nss_status (*_nss_getusersids)(const char *, char **, int *, + char *, size_t, int *); + enum nss_status status; + int nss_errno = 0; + char *s; + int i, num_groups = 0; + unsigned bufsize = 10; + char *buf; + + _nss_getusersids = find_fn(nss, "getusersids"); + + if (!_nss_getusersids) { + return -1; + } + +again: + buf = malloc(bufsize); + if (!buf) { + errno = ENOMEM; + return -1; + } + + status = _nss_getusersids(user_sid, &s, &num_groups, buf, bufsize, + &nss_errno); + + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + free(buf); + return -1; + } + + if (status == NSS_STATUS_TRYAGAIN) { + bufsize *= 2; + free(buf); + goto again; + } + + if (status != NSS_STATUS_SUCCESS) { + free(buf); + errno = nss_errno; + return -1; + } + + if (num_groups == 0) { + free(buf); + return 0; + } + + *sids = (char **)malloc(sizeof(char *) * (num_groups+1)); + if (! *sids) { + errno = ENOMEM; + free(buf); + return -1; + } + + for (i=0;i<num_groups;i++) { + (*sids)[i] = strdup(s); + s += strlen(s) + 1; + } + (*sids)[i] = NULL; + + free(buf); + + return 0; +} + +/* + convert a sid to a uid + Return 0 on success and -1 on error +*/ +int nss_sidtouid(struct nss_state *nss, const char *sid, uid_t *uid) +{ + enum nss_status (*_nss_sidtouid)(const char*, uid_t *, int*); + + enum nss_status status; + int nss_errno = 0; + + _nss_sidtouid = find_fn(nss, "sidtouid"); + + if (!_nss_sidtouid) { + return -1; + } + + status = _nss_sidtouid(sid, uid, &nss_errno); + + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + return 0; +} + +/* + convert a sid to a gid + Return 0 on success and -1 on error +*/ +int nss_sidtogid(struct nss_state *nss, const char *sid, gid_t *gid) +{ + enum nss_status (*_nss_sidtogid)(const char*, gid_t *, int*); + + enum nss_status status; + int nss_errno = 0; + + _nss_sidtogid = find_fn(nss, "sidtogid"); + + if (!_nss_sidtogid) { + return -1; + } + + status = _nss_sidtogid(sid, gid, &nss_errno); + + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + return 0; +} + +/* + convert a uid to a sid + caller frees + Return 0 on success and -1 on error +*/ +int nss_uidtosid(struct nss_state *nss, uid_t uid, char **sid) +{ + enum nss_status (*_nss_uidtosid)(uid_t, char **, char *, + size_t, int *); + enum nss_status status; + int nss_errno = 0; + char buf[200]; + + _nss_uidtosid = find_fn(nss, "uidtosid"); + + if (!_nss_uidtosid) { + return -1; + } + + status = _nss_uidtosid(uid, sid, buf, sizeof(buf), &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + *sid = strdup(*sid); + + return 0; +} + +/* + convert a gid to a sid + caller frees + Return 0 on success and -1 on error +*/ +int nss_gidtosid(struct nss_state *nss, gid_t gid, char **sid) +{ + enum nss_status (*_nss_gidtosid)(gid_t, char **, char *, + size_t, int *); + enum nss_status status; + int nss_errno = 0; + char buf[200]; + + _nss_gidtosid = find_fn(nss, "gidtosid"); + + if (!_nss_gidtosid) { + return -1; + } + + status = _nss_gidtosid(gid, sid, buf, sizeof(buf), &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + *sid = strdup(*sid); + + return 0; +} + diff --git a/examples/nss/nss_winbind.h b/examples/nss/nss_winbind.h new file mode 100644 index 0000000000..5a124a5a8e --- /dev/null +++ b/examples/nss/nss_winbind.h @@ -0,0 +1,97 @@ +/* + nss sample code for extended winbindd functionality + + Copyright (C) Andrew Tridgell (tridge@samba.org) + Copyright (C) Volker Lendecke (vl@samba.org) + + you are free to use this code in any way you see fit, including + without restriction, using this code in your own products. You do + not need to give any attribution. +*/ + +#define _GNU_SOURCE + +#include <pwd.h> +#include <grp.h> + +struct nss_state { + void *dl_handle; + char *nss_name; + char pwnam_buf[512]; +}; + +/* + establish a link to the nss library + Return 0 on success and -1 on error +*/ +int nss_open(struct nss_state *nss, const char *nss_path); + +/* + close and cleanup a nss state +*/ +void nss_close(struct nss_state *nss); + +/* + make a getpwnam call. + Return 0 on success and -1 on error +*/ +int nss_getpwent(struct nss_state *nss, struct passwd *pwd); + +/* + make a setpwent call. + Return 0 on success and -1 on error +*/ +int nss_setpwent(struct nss_state *nss); + +/* + make a endpwent call. + Return 0 on success and -1 on error +*/ +int nss_endpwent(struct nss_state *nss); + +/* + convert a name to a SID + caller frees + Return 0 on success and -1 on error +*/ +int nss_nametosid(struct nss_state *nss, const char *name, char **sid); + +/* + convert a SID to a name + caller frees + Return 0 on success and -1 on error +*/ +int nss_sidtoname(struct nss_state *nss, const char *sid, char **name); + +/* + return a list of group SIDs for a user SID + the returned list is NULL terminated + Return 0 on success and -1 on error +*/ +int nss_getusersids(struct nss_state *nss, const char *user_sid, char ***sids); + +/* + convert a sid to a uid + Return 0 on success and -1 on error +*/ +int nss_sidtouid(struct nss_state *nss, const char *sid, uid_t *uid); + +/* + convert a sid to a gid + Return 0 on success and -1 on error +*/ +int nss_sidtogid(struct nss_state *nss, const char *sid, gid_t *gid); + +/* + convert a uid to a sid + caller frees + Return 0 on success and -1 on error +*/ +int nss_uidtosid(struct nss_state *nss, uid_t uid, char **sid); + +/* + convert a gid to a sid + caller frees + Return 0 on success and -1 on error +*/ +int nss_gidtosid(struct nss_state *nss, gid_t gid, char **sid); diff --git a/examples/nss/wbtest.c b/examples/nss/wbtest.c new file mode 100644 index 0000000000..14265bd54c --- /dev/null +++ b/examples/nss/wbtest.c @@ -0,0 +1,111 @@ +/* + nss sample code for extended winbindd functionality + + Copyright (C) Andrew Tridgell (tridge@samba.org) + + you are free to use this code in any way you see fit, including + without restriction, using this code in your own products. You do + not need to give any attribution. +*/ + +/* + compile like this: + + cc -o wbtest wbtest.c nss_winbind.c -ldl + + and run like this: + + ./wbtest /lib/libnss_winbind.so +*/ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <nss.h> +#include <dlfcn.h> +#include <pwd.h> +#include <grp.h> +#include <errno.h> +#include <string.h> +#include <sys/types.h> + +#include "nss_winbind.h" + +static int nss_test_users(struct nss_state *nss) +{ + struct passwd pwd; + + if (nss_setpwent(nss) != 0) { + perror("setpwent"); + return -1; + } + + /* loop over all users */ + while ((nss_getpwent(nss, &pwd) == 0)) { + char *sid, **group_sids, *name2; + int i; + + printf("User %s\n", pwd.pw_name); + if (nss_nametosid(nss, pwd.pw_name, &sid) != 0) { + perror("nametosid"); + return -1; + } + printf("\tSID %s\n", sid); + + if (nss_sidtoname(nss, sid, &name2) != 0) { + perror("sidtoname"); + return -1; + } + printf("\tSID->name %s\n", name2); + + if (nss_getusersids(nss, sid, &group_sids) != 0) { + perror("getusersids"); + return -1; + } + + printf("\tGroups:\n"); + for (i=0; group_sids[i]; i++) { + printf("\t\t%s\n", group_sids[i]); + free(group_sids[i]); + } + + free(sid); + free(name2); + free(group_sids); + } + + + if (nss_endpwent(nss) != 0) { + perror("endpwent"); + return -1; + } + + return 0; +} + + +/* + main program. It lists all users, listing user SIDs for each user + */ +int main(int argc, char *argv[]) +{ + struct nss_state nss; + const char *so_path = "/lib/libnss_winbind.so"; + int ret; + + if (argc > 1) { + so_path = argv[1]; + } + + if (nss_open(&nss, so_path) != 0) { + perror("nss_open"); + exit(1); + } + + ret = nss_test_users(&nss); + + nss_close(&nss); + + return ret; +} diff --git a/examples/pam_winbind/pam_winbind.conf b/examples/pam_winbind/pam_winbind.conf new file mode 100644 index 0000000000..a9e02a833a --- /dev/null +++ b/examples/pam_winbind/pam_winbind.conf @@ -0,0 +1,35 @@ +# +# pam_winbind configuration file +# +# /etc/security/pam_winbind.conf +# + +[global] + +# turn on debugging +;debug = no + +# turn on extended PAM state debugging +;debug_state = no + +# request a cached login if possible +# (needs "winbind offline logon = yes" in smb.conf) +;cached_login = no + +# authenticate using kerberos +;krb5_auth = no + +# when using kerberos, request a "FILE" krb5 credential cache type +# (leave empty to just do krb5 authentication but not have a ticket +# afterwards) +;krb5_ccache_type = + +# make successful authentication dependend on membership of one SID +# (can also take a name) +;require_membership_of = + +# password expiry warning period in days +;warn_pwd_expire = 14 + +# omit pam conversations +;silent = no diff --git a/examples/pcap2nbench/COPYING b/examples/pcap2nbench/COPYING new file mode 100644 index 0000000000..94a9ed024d --- /dev/null +++ b/examples/pcap2nbench/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/examples/pcap2nbench/Makefile b/examples/pcap2nbench/Makefile new file mode 100644 index 0000000000..c1221b3876 --- /dev/null +++ b/examples/pcap2nbench/Makefile @@ -0,0 +1,33 @@ +############################################################################### +## +## pcap2nbench - Converts libpcap network traces to nbench input +## Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> +## +## 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/>. +## +## Written by Anthony Liguori <aliguori@us.ibm.com> +## +############################################################################### + +OBJ=main.o ethernet.o ip.o tcp.o smb.o ntcreateandxrequest.o readandxrequest.o writeandxrequest.o closerequest.o ntcreateandxresponse.o +PROG=pcap2nbench +CXXFLAGS=-g -Wall +LDFLAGS= +LIB=-lpcap + +$(PROG): $(OBJ) + $(CXX) -o $(PROG) $(CXXFLAGS) $(OBJ) $(LDFLAGS) $(LIB) + +clean: + $(RM) $(OBJ) $(PROG) diff --git a/examples/pcap2nbench/README b/examples/pcap2nbench/README new file mode 100644 index 0000000000..46f851439a --- /dev/null +++ b/examples/pcap2nbench/README @@ -0,0 +1,24 @@ +pcap2nbench +----------- + +About + +This program converts a libpcap network trace file (produced by ethereal or +another pcap-aware network analyzer) into a output suitable for nbench. The +only option it takes it -i which supresses any reads/writes/closes that use a +FID that does not have a corresponding ntcreateandx + +Limitations + +1) pcap2nbench does not handle ip fragmentation. You should not normally see + very much fragmentation so this should not really affect a workload. +2) unicode on the wire is not supported. +3) only a limited number of SMBs are supported. Namely: NtCreateAndX, + ReadAndX, WriteAndX, and Close. In addition, not all WCTs are supported on + each of these SMBs. + +Future Work + +It would be nice to use Samba or Ethereal's parsing code to handle the SMBs. +At first glance, this seemed non-trivial. It would also be nice to handle some +Trans2 SMBs specifically QueryFileInfo and QueryPathInfo. diff --git a/examples/pcap2nbench/closerequest.cpp b/examples/pcap2nbench/closerequest.cpp new file mode 100644 index 0000000000..b31a1b6731 --- /dev/null +++ b/examples/pcap2nbench/closerequest.cpp @@ -0,0 +1,45 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#include <netinet/in.h> + +#include "closerequest.hpp" + +CloseRequest::CloseRequest(const uint8_t *data, size_t size) +{ + if (size < 9) { + std::cerr << "Invalid Close Request" << std::endl; + return; + } + + word_count = data[0]; + memcpy(&fid, data + 1, 2); + memcpy(&last_write, data + 3, 4); + memcpy(&byte_count, data + 7, 2); +} + +std::ostream &operator<<(std::ostream &lhs, const CloseRequest &rhs) +{ + lhs << "Word Count: " << (uint16_t)rhs.word_count << std::endl + << "Fid: " << rhs.fid << std::endl + << "Last Write: " << rhs.last_write << std::endl + << "Byte Count: " << rhs.byte_count << std::endl; + return lhs; +} diff --git a/examples/pcap2nbench/closerequest.hpp b/examples/pcap2nbench/closerequest.hpp new file mode 100644 index 0000000000..fe8866f5bc --- /dev/null +++ b/examples/pcap2nbench/closerequest.hpp @@ -0,0 +1,43 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#ifndef _CLOSE_REQUEST_HPP +#define _CLOSE_REQUEST_HPP + +#include <iostream> +#include <stdint.h> + +struct CloseRequest { + enum { + COMMAND = 0x04 + }; + + CloseRequest() {} + CloseRequest(const uint8_t *data, size_t size); + + uint8_t word_count; + uint16_t fid; + uint32_t last_write; + uint16_t byte_count; +}; + +std::ostream &operator<<(std::ostream &lhs, const CloseRequest &rhs); + +#endif diff --git a/examples/pcap2nbench/ethernet.cpp b/examples/pcap2nbench/ethernet.cpp new file mode 100644 index 0000000000..4d531594e2 --- /dev/null +++ b/examples/pcap2nbench/ethernet.cpp @@ -0,0 +1,61 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#include <netinet/in.h> + +#include "ethernet.hpp" + +ethernet::ethernet(const uint8_t *data, size_t length) { + if (length < 14) { + std::cerr << "Invalid ethernet packet" << std::endl; + } + memcpy(dst, data, sizeof(dst)); + memcpy(src, data + 6, sizeof(src)); + memcpy(&type, data + 12, sizeof(type)); + type = ntohs(type); +} + +std::ostream &operator<<(std::ostream &lhs, const ethernet &rhs) +{ + lhs << "Destination: "; + for (int i = 0; i < 6; i++) { + char buf[3]; + sprintf(buf, "%.2x", rhs.dst[i]); + if (i) lhs << ":"; + lhs << buf; + } + lhs << std::endl; + + lhs << "Source: "; + for (int i = 0; i < 6; i++) { + char buf[3]; + sprintf(buf, "%.2x", rhs.src[i]); + if (i) lhs << ":"; + lhs << buf; + } + lhs << std::endl; + + lhs << "Type: "; + char buf[7]; + sprintf(buf, "%.4x", rhs.type); + lhs << buf << std::endl; + + return lhs; +} diff --git a/examples/pcap2nbench/ethernet.hpp b/examples/pcap2nbench/ethernet.hpp new file mode 100644 index 0000000000..baaca5afd1 --- /dev/null +++ b/examples/pcap2nbench/ethernet.hpp @@ -0,0 +1,36 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#ifndef ETHERNET_HPP +#define ETHERNET_HPP + +#include <stdint.h> +#include <iostream> + +struct ethernet { + ethernet(const uint8_t *data, size_t length); + uint8_t dst[6]; + uint8_t src[6]; + uint16_t type; +}; + +std::ostream &operator<<(std::ostream &lhs, const ethernet &rhs); + +#endif diff --git a/examples/pcap2nbench/ip.cpp b/examples/pcap2nbench/ip.cpp new file mode 100644 index 0000000000..8f1d821404 --- /dev/null +++ b/examples/pcap2nbench/ip.cpp @@ -0,0 +1,65 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#include <netinet/in.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include "ip.hpp" + +ip::ip(const uint8_t *data, size_t length) +{ + if (length < 20) { + std::cerr << "Invalid ip packet" << std::endl; + } + + version = (data[0] >> 4) & 0x0F; + header_length = (data[0] & 0x0F) * 4; + dsfield = data[1]; + memcpy(&total_length, data + 2, 2); + total_length = ntohs(total_length); + memcpy(&id, data + 4, 2); + id = ntohs(id); + flags = (data[6] >> 4) & 0x0F; + fragment_offset = ((data[6] & 0x0F) << 4) | data[7]; + ttl = data[8]; + protocol = data[9]; + memcpy(&checksum, data + 10, 2); + checksum = ntohs(checksum); + memcpy(&source, data + 12, 4); + memcpy(&destination, data + 16, 4); +} + +std::ostream &operator<<(std::ostream &lhs, const ip &rhs) +{ + lhs << "Version: " << (uint32_t)rhs.version << std::endl + << "Header length: " << (uint32_t)rhs.header_length << std::endl + << "Differentiated Services Field: " << (uint32_t)rhs.dsfield << std::endl + << "Total Length: " << (uint32_t)rhs.total_length << std::endl + << "Identification: " << (uint32_t)rhs.id << std::endl + << "Flags: " << (uint32_t)rhs.flags << std::endl + << "Fragment offset: " << (uint32_t)rhs.fragment_offset << std::endl + << "TTL: " << (uint32_t)rhs.ttl << std::endl + << "Protocol: " << (uint32_t)rhs.protocol << std::endl + << "Checksum: " << (uint32_t)rhs.checksum << std::endl + << "Source: " << inet_ntoa(*((in_addr *)&rhs.source)) << std::endl + << "Destination: " << inet_ntoa(*((in_addr *)&rhs.destination)) << std::endl; + + return lhs; +} diff --git a/examples/pcap2nbench/ip.hpp b/examples/pcap2nbench/ip.hpp new file mode 100644 index 0000000000..da1f0d35d1 --- /dev/null +++ b/examples/pcap2nbench/ip.hpp @@ -0,0 +1,46 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#ifndef IP_HPP +#define IP_HPP + +#include <stdint.h> +#include <iostream> + +struct ip { + ip(const uint8_t *data, size_t length); + + uint8_t version; + uint8_t header_length; + uint8_t dsfield; + uint16_t total_length; + uint16_t id; + uint8_t flags; + uint16_t fragment_offset; + uint8_t ttl; + uint8_t protocol; + uint16_t checksum; + uint32_t source; + uint32_t destination; +}; + +std::ostream &operator<<(std::ostream &lhs, const ip &rhs); + +#endif diff --git a/examples/pcap2nbench/main.cpp b/examples/pcap2nbench/main.cpp new file mode 100644 index 0000000000..e07b4735bd --- /dev/null +++ b/examples/pcap2nbench/main.cpp @@ -0,0 +1,738 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#include <iostream> +#include <pcap.h> +#include <getopt.h> +#include <stdint.h> +#include <netinet/in.h> + +#include "ethernet.hpp" +#include "ip.hpp" +#include "tcp.hpp" +#include "smb.hpp" +#include "ntcreateandxrequest.hpp" +#include "ntcreateandxresponse.hpp" +#include "readandxrequest.hpp" +#include "writeandxrequest.hpp" +#include "closerequest.hpp" + +#include <vector> +#include <set> + + +/* derived from source/include/nterr.h */ +const char *nt_status_to_string[] = { + "NT_STATUS_OK", /* 0x0000 */ + "NT_STATUS_UNSUCCESSFUL", /* 0x0001 */ + "NT_STATUS_NOT_IMPLEMENTED", /* 0x0002 */ + "NT_STATUS_INVALID_INFO_CLASS", /* 0x0003 */ + "NT_STATUS_INFO_LENGTH_MISMATCH", /* 0x0004 */ + "NT_STATUS_ACCESS_VIOLATION", /* 0x0005 */ + "NT_STATUS_IN_PAGE_ERROR", /* 0x0006 */ + "NT_STATUS_PAGEFILE_QUOTA", /* 0x0007 */ + "NT_STATUS_INVALID_HANDLE", /* 0x0008 */ + "NT_STATUS_BAD_INITIAL_STACK", /* 0x0009 */ + "NT_STATUS_BAD_INITIAL_PC", /* 0x000a */ + "NT_STATUS_INVALID_CID", /* 0x000b */ + "NT_STATUS_TIMER_NOT_CANCELED", /* 0x000c */ + "NT_STATUS_INVALID_PARAMETER", /* 0x000d */ + "NT_STATUS_NO_SUCH_DEVICE", /* 0x000e */ + "NT_STATUS_NO_SUCH_FILE", /* 0x000f */ + "NT_STATUS_INVALID_DEVICE_REQUEST", /* 0x0010 */ + "NT_STATUS_END_OF_FILE", /* 0x0011 */ + "NT_STATUS_WRONG_VOLUME", /* 0x0012 */ + "NT_STATUS_NO_MEDIA_IN_DEVICE", /* 0x0013 */ + "NT_STATUS_UNRECOGNIZED_MEDIA", /* 0x0014 */ + "NT_STATUS_NONEXISTENT_SECTOR", /* 0x0015 */ + "NT_STATUS_MORE_PROCESSING_REQUIRED", /* 0x0016 */ + "NT_STATUS_NO_MEMORY", /* 0x0017 */ + "NT_STATUS_CONFLICTING_ADDRESSES", /* 0x0018 */ + "NT_STATUS_NOT_MAPPED_VIEW", /* 0x0019 */ + "NT_STATUS_UNABLE_TO_FREE_VM", /* 0x001a */ + "NT_STATUS_UNABLE_TO_DELETE_SECTION", /* 0x001b */ + "NT_STATUS_INVALID_SYSTEM_SERVICE", /* 0x001c */ + "NT_STATUS_ILLEGAL_INSTRUCTION", /* 0x001d */ + "NT_STATUS_INVALID_LOCK_SEQUENCE", /* 0x001e */ + "NT_STATUS_INVALID_VIEW_SIZE", /* 0x001f */ + "NT_STATUS_INVALID_FILE_FOR_SECTION", /* 0x0020 */ + "NT_STATUS_ALREADY_COMMITTED", /* 0x0021 */ + "NT_STATUS_ACCESS_DENIED", /* 0x0022 */ + "NT_STATUS_BUFFER_TOO_SMALL", /* 0x0023 */ + "NT_STATUS_OBJECT_TYPE_MISMATCH", /* 0x0024 */ + "NT_STATUS_NONCONTINUABLE_EXCEPTION", /* 0x0025 */ + "NT_STATUS_INVALID_DISPOSITION", /* 0x0026 */ + "NT_STATUS_UNWIND", /* 0x0027 */ + "NT_STATUS_BAD_STACK", /* 0x0028 */ + "NT_STATUS_INVALID_UNWIND_TARGET", /* 0x0029 */ + "NT_STATUS_NOT_LOCKED", /* 0x002a */ + "NT_STATUS_PARITY_ERROR", /* 0x002b */ + "NT_STATUS_UNABLE_TO_DECOMMIT_VM", /* 0x002c */ + "NT_STATUS_NOT_COMMITTED", /* 0x002d */ + "NT_STATUS_INVALID_PORT_ATTRIBUTES", /* 0x002e */ + "NT_STATUS_PORT_MESSAGE_TOO_LONG", /* 0x002f */ + "NT_STATUS_INVALID_PARAMETER_MIX", /* 0x0030 */ + "NT_STATUS_INVALID_QUOTA_LOWER", /* 0x0031 */ + "NT_STATUS_DISK_CORRUPT_ERROR", /* 0x0032 */ + "NT_STATUS_OBJECT_NAME_INVALID", /* 0x0033 */ + "NT_STATUS_OBJECT_NAME_NOT_FOUND", /* 0x0034 */ + "NT_STATUS_OBJECT_NAME_COLLISION", /* 0x0035 */ + "NT_STATUS_HANDLE_NOT_WAITABLE", /* 0x0036 */ + "NT_STATUS_PORT_DISCONNECTED", /* 0x0037 */ + "NT_STATUS_DEVICE_ALREADY_ATTACHED", /* 0x0038 */ + "NT_STATUS_OBJECT_PATH_INVALID", /* 0x0039 */ + "NT_STATUS_OBJECT_PATH_NOT_FOUND", /* 0x003a */ + "NT_STATUS_OBJECT_PATH_SYNTAX_BAD", /* 0x003b */ + "NT_STATUS_DATA_OVERRUN", /* 0x003c */ + "NT_STATUS_DATA_LATE_ERROR", /* 0x003d */ + "NT_STATUS_DATA_ERROR", /* 0x003e */ + "NT_STATUS_CRC_ERROR", /* 0x003f */ + "NT_STATUS_SECTION_TOO_BIG", /* 0x0040 */ + "NT_STATUS_PORT_CONNECTION_REFUSED", /* 0x0041 */ + "NT_STATUS_INVALID_PORT_HANDLE", /* 0x0042 */ + "NT_STATUS_SHARING_VIOLATION", /* 0x0043 */ + "NT_STATUS_QUOTA_EXCEEDED", /* 0x0044 */ + "NT_STATUS_INVALID_PAGE_PROTECTION", /* 0x0045 */ + "NT_STATUS_MUTANT_NOT_OWNED", /* 0x0046 */ + "NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED", /* 0x0047 */ + "NT_STATUS_PORT_ALREADY_SET", /* 0x0048 */ + "NT_STATUS_SECTION_NOT_IMAGE", /* 0x0049 */ + "NT_STATUS_SUSPEND_COUNT_EXCEEDED", /* 0x004a */ + "NT_STATUS_THREAD_IS_TERMINATING", /* 0x004b */ + "NT_STATUS_BAD_WORKING_SET_LIMIT", /* 0x004c */ + "NT_STATUS_INCOMPATIBLE_FILE_MAP", /* 0x004d */ + "NT_STATUS_SECTION_PROTECTION", /* 0x004e */ + "NT_STATUS_EAS_NOT_SUPPORTED", /* 0x004f */ + "NT_STATUS_EA_TOO_LARGE", /* 0x0050 */ + "NT_STATUS_NONEXISTENT_EA_ENTRY", /* 0x0051 */ + "NT_STATUS_NO_EAS_ON_FILE", /* 0x0052 */ + "NT_STATUS_EA_CORRUPT_ERROR", /* 0x0053 */ + "NT_STATUS_FILE_LOCK_CONFLICT", /* 0x0054 */ + "NT_STATUS_LOCK_NOT_GRANTED", /* 0x0055 */ + "NT_STATUS_DELETE_PENDING", /* 0x0056 */ + "NT_STATUS_CTL_FILE_NOT_SUPPORTED", /* 0x0057 */ + "NT_STATUS_UNKNOWN_REVISION", /* 0x0058 */ + "NT_STATUS_REVISION_MISMATCH", /* 0x0059 */ + "NT_STATUS_INVALID_OWNER", /* 0x005a */ + "NT_STATUS_INVALID_PRIMARY_GROUP", /* 0x005b */ + "NT_STATUS_NO_IMPERSONATION_TOKEN", /* 0x005c */ + "NT_STATUS_CANT_DISABLE_MANDATORY", /* 0x005d */ + "NT_STATUS_NO_LOGON_SERVERS", /* 0x005e */ + "NT_STATUS_NO_SUCH_LOGON_SESSION", /* 0x005f */ + "NT_STATUS_NO_SUCH_PRIVILEGE", /* 0x0060 */ + "NT_STATUS_PRIVILEGE_NOT_HELD", /* 0x0061 */ + "NT_STATUS_INVALID_ACCOUNT_NAME", /* 0x0062 */ + "NT_STATUS_USER_EXISTS", /* 0x0063 */ + "NT_STATUS_NO_SUCH_USER", /* 0x0064 */ + "NT_STATUS_GROUP_EXISTS", /* 0x0065 */ + "NT_STATUS_NO_SUCH_GROUP", /* 0x0066 */ + "NT_STATUS_MEMBER_IN_GROUP", /* 0x0067 */ + "NT_STATUS_MEMBER_NOT_IN_GROUP", /* 0x0068 */ + "NT_STATUS_LAST_ADMIN", /* 0x0069 */ + "NT_STATUS_WRONG_PASSWORD", /* 0x006a */ + "NT_STATUS_ILL_FORMED_PASSWORD", /* 0x006b */ + "NT_STATUS_PASSWORD_RESTRICTION", /* 0x006c */ + "NT_STATUS_LOGON_FAILURE", /* 0x006d */ + "NT_STATUS_ACCOUNT_RESTRICTION", /* 0x006e */ + "NT_STATUS_INVALID_LOGON_HOURS", /* 0x006f */ + "NT_STATUS_INVALID_WORKSTATION", /* 0x0070 */ + "NT_STATUS_PASSWORD_EXPIRED", /* 0x0071 */ + "NT_STATUS_ACCOUNT_DISABLED", /* 0x0072 */ + "NT_STATUS_NONE_MAPPED", /* 0x0073 */ + "NT_STATUS_TOO_MANY_LUIDS_REQUESTED", /* 0x0074 */ + "NT_STATUS_LUIDS_EXHAUSTED", /* 0x0075 */ + "NT_STATUS_INVALID_SUB_AUTHORITY", /* 0x0076 */ + "NT_STATUS_INVALID_ACL", /* 0x0077 */ + "NT_STATUS_INVALID_SID", /* 0x0078 */ + "NT_STATUS_INVALID_SECURITY_DESCR", /* 0x0079 */ + "NT_STATUS_PROCEDURE_NOT_FOUND", /* 0x007a */ + "NT_STATUS_INVALID_IMAGE_FORMAT", /* 0x007b */ + "NT_STATUS_NO_TOKEN", /* 0x007c */ + "NT_STATUS_BAD_INHERITANCE_ACL", /* 0x007d */ + "NT_STATUS_RANGE_NOT_LOCKED", /* 0x007e */ + "NT_STATUS_DISK_FULL", /* 0x007f */ + "NT_STATUS_SERVER_DISABLED", /* 0x0080 */ + "NT_STATUS_SERVER_NOT_DISABLED", /* 0x0081 */ + "NT_STATUS_TOO_MANY_GUIDS_REQUESTED", /* 0x0082 */ + "NT_STATUS_GUIDS_EXHAUSTED", /* 0x0083 */ + "NT_STATUS_INVALID_ID_AUTHORITY", /* 0x0084 */ + "NT_STATUS_AGENTS_EXHAUSTED", /* 0x0085 */ + "NT_STATUS_INVALID_VOLUME_LABEL", /* 0x0086 */ + "NT_STATUS_SECTION_NOT_EXTENDED", /* 0x0087 */ + "NT_STATUS_NOT_MAPPED_DATA", /* 0x0088 */ + "NT_STATUS_RESOURCE_DATA_NOT_FOUND", /* 0x0089 */ + "NT_STATUS_RESOURCE_TYPE_NOT_FOUND", /* 0x008a */ + "NT_STATUS_RESOURCE_NAME_NOT_FOUND", /* 0x008b */ + "NT_STATUS_ARRAY_BOUNDS_EXCEEDED", /* 0x008c */ + "NT_STATUS_FLOAT_DENORMAL_OPERAND", /* 0x008d */ + "NT_STATUS_FLOAT_DIVIDE_BY_ZERO", /* 0x008e */ + "NT_STATUS_FLOAT_INEXACT_RESULT", /* 0x008f */ + "NT_STATUS_FLOAT_INVALID_OPERATION", /* 0x0090 */ + "NT_STATUS_FLOAT_OVERFLOW", /* 0x0091 */ + "NT_STATUS_FLOAT_STACK_CHECK", /* 0x0092 */ + "NT_STATUS_FLOAT_UNDERFLOW", /* 0x0093 */ + "NT_STATUS_INTEGER_DIVIDE_BY_ZERO", /* 0x0094 */ + "NT_STATUS_INTEGER_OVERFLOW", /* 0x0095 */ + "NT_STATUS_PRIVILEGED_INSTRUCTION", /* 0x0096 */ + "NT_STATUS_TOO_MANY_PAGING_FILES", /* 0x0097 */ + "NT_STATUS_FILE_INVALID", /* 0x0098 */ + "NT_STATUS_ALLOTTED_SPACE_EXCEEDED", /* 0x0099 */ + "NT_STATUS_INSUFFICIENT_RESOURCES", /* 0x009a */ + "NT_STATUS_DFS_EXIT_PATH_FOUND", /* 0x009b */ + "NT_STATUS_DEVICE_DATA_ERROR", /* 0x009c */ + "NT_STATUS_DEVICE_NOT_CONNECTED", /* 0x009d */ + "NT_STATUS_DEVICE_POWER_FAILURE", /* 0x009e */ + "NT_STATUS_FREE_VM_NOT_AT_BASE", /* 0x009f */ + "NT_STATUS_MEMORY_NOT_ALLOCATED", /* 0x00a0 */ + "NT_STATUS_WORKING_SET_QUOTA", /* 0x00a1 */ + "NT_STATUS_MEDIA_WRITE_PROTECTED", /* 0x00a2 */ + "NT_STATUS_DEVICE_NOT_READY", /* 0x00a3 */ + "NT_STATUS_INVALID_GROUP_ATTRIBUTES", /* 0x00a4 */ + "NT_STATUS_BAD_IMPERSONATION_LEVEL", /* 0x00a5 */ + "NT_STATUS_CANT_OPEN_ANONYMOUS", /* 0x00a6 */ + "NT_STATUS_BAD_VALIDATION_CLASS", /* 0x00a7 */ + "NT_STATUS_BAD_TOKEN_TYPE", /* 0x00a8 */ + "NT_STATUS_BAD_MASTER_BOOT_RECORD", /* 0x00a9 */ + "NT_STATUS_INSTRUCTION_MISALIGNMENT", /* 0x00aa */ + "NT_STATUS_INSTANCE_NOT_AVAILABLE", /* 0x00ab */ + "NT_STATUS_PIPE_NOT_AVAILABLE", /* 0x00ac */ + "NT_STATUS_INVALID_PIPE_STATE", /* 0x00ad */ + "NT_STATUS_PIPE_BUSY", /* 0x00ae */ + "NT_STATUS_ILLEGAL_FUNCTION", /* 0x00af */ + "NT_STATUS_PIPE_DISCONNECTED", /* 0x00b0 */ + "NT_STATUS_PIPE_CLOSING", /* 0x00b1 */ + "NT_STATUS_PIPE_CONNECTED", /* 0x00b2 */ + "NT_STATUS_PIPE_LISTENING", /* 0x00b3 */ + "NT_STATUS_INVALID_READ_MODE", /* 0x00b4 */ + "NT_STATUS_IO_TIMEOUT", /* 0x00b5 */ + "NT_STATUS_FILE_FORCED_CLOSED", /* 0x00b6 */ + "NT_STATUS_PROFILING_NOT_STARTED", /* 0x00b7 */ + "NT_STATUS_PROFILING_NOT_STOPPED", /* 0x00b8 */ + "NT_STATUS_COULD_NOT_INTERPRET", /* 0x00b9 */ + "NT_STATUS_FILE_IS_A_DIRECTORY", /* 0x00ba */ + "NT_STATUS_NOT_SUPPORTED", /* 0x00bb */ + "NT_STATUS_REMOTE_NOT_LISTENING", /* 0x00bc */ + "NT_STATUS_DUPLICATE_NAME", /* 0x00bd */ + "NT_STATUS_BAD_NETWORK_PATH", /* 0x00be */ + "NT_STATUS_NETWORK_BUSY", /* 0x00bf */ + "NT_STATUS_DEVICE_DOES_NOT_EXIST", /* 0x00c0 */ + "NT_STATUS_TOO_MANY_COMMANDS", /* 0x00c1 */ + "NT_STATUS_ADAPTER_HARDWARE_ERROR", /* 0x00c2 */ + "NT_STATUS_INVALID_NETWORK_RESPONSE", /* 0x00c3 */ + "NT_STATUS_UNEXPECTED_NETWORK_ERROR", /* 0x00c4 */ + "NT_STATUS_BAD_REMOTE_ADAPTER", /* 0x00c5 */ + "NT_STATUS_PRINT_QUEUE_FULL", /* 0x00c6 */ + "NT_STATUS_NO_SPOOL_SPACE", /* 0x00c7 */ + "NT_STATUS_PRINT_CANCELLED", /* 0x00c8 */ + "NT_STATUS_NETWORK_NAME_DELETED", /* 0x00c9 */ + "NT_STATUS_NETWORK_ACCESS_DENIED", /* 0x00ca */ + "NT_STATUS_BAD_DEVICE_TYPE", /* 0x00cb */ + "NT_STATUS_BAD_NETWORK_NAME", /* 0x00cc */ + "NT_STATUS_TOO_MANY_NAMES", /* 0x00cd */ + "NT_STATUS_TOO_MANY_SESSIONS", /* 0x00ce */ + "NT_STATUS_SHARING_PAUSED", /* 0x00cf */ + "NT_STATUS_REQUEST_NOT_ACCEPTED", /* 0x00d0 */ + "NT_STATUS_REDIRECTOR_PAUSED", /* 0x00d1 */ + "NT_STATUS_NET_WRITE_FAULT", /* 0x00d2 */ + "NT_STATUS_PROFILING_AT_LIMIT", /* 0x00d3 */ + "NT_STATUS_NOT_SAME_DEVICE", /* 0x00d4 */ + "NT_STATUS_FILE_RENAMED", /* 0x00d5 */ + "NT_STATUS_VIRTUAL_CIRCUIT_CLOSED", /* 0x00d6 */ + "NT_STATUS_NO_SECURITY_ON_OBJECT", /* 0x00d7 */ + "NT_STATUS_CANT_WAIT", /* 0x00d8 */ + "NT_STATUS_PIPE_EMPTY", /* 0x00d9 */ + "NT_STATUS_CANT_ACCESS_DOMAIN_INFO", /* 0x00da */ + "NT_STATUS_CANT_TERMINATE_SELF", /* 0x00db */ + "NT_STATUS_INVALID_SERVER_STATE", /* 0x00dc */ + "NT_STATUS_INVALID_DOMAIN_STATE", /* 0x00dd */ + "NT_STATUS_INVALID_DOMAIN_ROLE", /* 0x00de */ + "NT_STATUS_NO_SUCH_DOMAIN", /* 0x00df */ + "NT_STATUS_DOMAIN_EXISTS", /* 0x00e0 */ + "NT_STATUS_DOMAIN_LIMIT_EXCEEDED", /* 0x00e1 */ + "NT_STATUS_OPLOCK_NOT_GRANTED", /* 0x00e2 */ + "NT_STATUS_INVALID_OPLOCK_PROTOCOL", /* 0x00e3 */ + "NT_STATUS_INTERNAL_DB_CORRUPTION", /* 0x00e4 */ + "NT_STATUS_INTERNAL_ERROR", /* 0x00e5 */ + "NT_STATUS_GENERIC_NOT_MAPPED", /* 0x00e6 */ + "NT_STATUS_BAD_DESCRIPTOR_FORMAT", /* 0x00e7 */ + "NT_STATUS_INVALID_USER_BUFFER", /* 0x00e8 */ + "NT_STATUS_UNEXPECTED_IO_ERROR", /* 0x00e9 */ + "NT_STATUS_UNEXPECTED_MM_CREATE_ERR", /* 0x00ea */ + "NT_STATUS_UNEXPECTED_MM_MAP_ERROR", /* 0x00eb */ + "NT_STATUS_UNEXPECTED_MM_EXTEND_ERR", /* 0x00ec */ + "NT_STATUS_NOT_LOGON_PROCESS", /* 0x00ed */ + "NT_STATUS_LOGON_SESSION_EXISTS", /* 0x00ee */ + "NT_STATUS_INVALID_PARAMETER_1", /* 0x00ef */ + "NT_STATUS_INVALID_PARAMETER_2", /* 0x00f0 */ + "NT_STATUS_INVALID_PARAMETER_3", /* 0x00f1 */ + "NT_STATUS_INVALID_PARAMETER_4", /* 0x00f2 */ + "NT_STATUS_INVALID_PARAMETER_5", /* 0x00f3 */ + "NT_STATUS_INVALID_PARAMETER_6", /* 0x00f4 */ + "NT_STATUS_INVALID_PARAMETER_7", /* 0x00f5 */ + "NT_STATUS_INVALID_PARAMETER_8", /* 0x00f6 */ + "NT_STATUS_INVALID_PARAMETER_9", /* 0x00f7 */ + "NT_STATUS_INVALID_PARAMETER_10", /* 0x00f8 */ + "NT_STATUS_INVALID_PARAMETER_11", /* 0x00f9 */ + "NT_STATUS_INVALID_PARAMETER_12", /* 0x00fa */ + "NT_STATUS_REDIRECTOR_NOT_STARTED", /* 0x00fb */ + "NT_STATUS_REDIRECTOR_STARTED", /* 0x00fc */ + "NT_STATUS_STACK_OVERFLOW", /* 0x00fd */ + "NT_STATUS_NO_SUCH_PACKAGE", /* 0x00fe */ + "NT_STATUS_BAD_FUNCTION_TABLE", /* 0x00ff */ + "NT_STATUS_DIRECTORY_NOT_EMPTY", /* 0x0101 */ + "NT_STATUS_FILE_CORRUPT_ERROR", /* 0x0102 */ + "NT_STATUS_NOT_A_DIRECTORY", /* 0x0103 */ + "NT_STATUS_BAD_LOGON_SESSION_STATE", /* 0x0104 */ + "NT_STATUS_LOGON_SESSION_COLLISION", /* 0x0105 */ + "NT_STATUS_NAME_TOO_LONG", /* 0x0106 */ + "NT_STATUS_FILES_OPEN", /* 0x0107 */ + "NT_STATUS_CONNECTION_IN_USE", /* 0x0108 */ + "NT_STATUS_MESSAGE_NOT_FOUND", /* 0x0109 */ + "NT_STATUS_PROCESS_IS_TERMINATING", /* 0x010a */ + "NT_STATUS_INVALID_LOGON_TYPE", /* 0x010b */ + "NT_STATUS_NO_GUID_TRANSLATION", /* 0x010c */ + "NT_STATUS_CANNOT_IMPERSONATE", /* 0x010d */ + "NT_STATUS_IMAGE_ALREADY_LOADED", /* 0x010e */ + "NT_STATUS_ABIOS_NOT_PRESENT", /* 0x010f */ + "NT_STATUS_ABIOS_LID_NOT_EXIST", /* 0x0110 */ + "NT_STATUS_ABIOS_LID_ALREADY_OWNED", /* 0x0111 */ + "NT_STATUS_ABIOS_NOT_LID_OWNER", /* 0x0112 */ + "NT_STATUS_ABIOS_INVALID_COMMAND", /* 0x0113 */ + "NT_STATUS_ABIOS_INVALID_LID", /* 0x0114 */ + "NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE", /* 0x0115 */ + "NT_STATUS_ABIOS_INVALID_SELECTOR", /* 0x0116 */ + "NT_STATUS_NO_LDT", /* 0x0117 */ + "NT_STATUS_INVALID_LDT_SIZE", /* 0x0118 */ + "NT_STATUS_INVALID_LDT_OFFSET", /* 0x0119 */ + "NT_STATUS_INVALID_LDT_DESCRIPTOR", /* 0x011a */ + "NT_STATUS_INVALID_IMAGE_NE_FORMAT", /* 0x011b */ + "NT_STATUS_RXACT_INVALID_STATE", /* 0x011c */ + "NT_STATUS_RXACT_COMMIT_FAILURE", /* 0x011d */ + "NT_STATUS_MAPPED_FILE_SIZE_ZERO", /* 0x011e */ + "NT_STATUS_TOO_MANY_OPENED_FILES", /* 0x011f */ + "NT_STATUS_CANCELLED", /* 0x0120 */ + "NT_STATUS_CANNOT_DELETE", /* 0x0121 */ + "NT_STATUS_INVALID_COMPUTER_NAME", /* 0x0122 */ + "NT_STATUS_FILE_DELETED", /* 0x0123 */ + "NT_STATUS_SPECIAL_ACCOUNT", /* 0x0124 */ + "NT_STATUS_SPECIAL_GROUP", /* 0x0125 */ + "NT_STATUS_SPECIAL_USER", /* 0x0126 */ + "NT_STATUS_MEMBERS_PRIMARY_GROUP", /* 0x0127 */ + "NT_STATUS_FILE_CLOSED", /* 0x0128 */ + "NT_STATUS_TOO_MANY_THREADS", /* 0x0129 */ + "NT_STATUS_THREAD_NOT_IN_PROCESS", /* 0x012a */ + "NT_STATUS_TOKEN_ALREADY_IN_USE", /* 0x012b */ + "NT_STATUS_PAGEFILE_QUOTA_EXCEEDED", /* 0x012c */ + "NT_STATUS_COMMITMENT_LIMIT", /* 0x012d */ + "NT_STATUS_INVALID_IMAGE_LE_FORMAT", /* 0x012e */ + "NT_STATUS_INVALID_IMAGE_NOT_MZ", /* 0x012f */ + "NT_STATUS_INVALID_IMAGE_PROTECT", /* 0x0130 */ + "NT_STATUS_INVALID_IMAGE_WIN_16", /* 0x0131 */ + "NT_STATUS_LOGON_SERVER_CONFLICT", /* 0x0132 */ + "NT_STATUS_TIME_DIFFERENCE_AT_DC", /* 0x0133 */ + "NT_STATUS_SYNCHRONIZATION_REQUIRED", /* 0x0134 */ + "NT_STATUS_DLL_NOT_FOUND", /* 0x0135 */ + "NT_STATUS_OPEN_FAILED", /* 0x0136 */ + "NT_STATUS_IO_PRIVILEGE_FAILED", /* 0x0137 */ + "NT_STATUS_ORDINAL_NOT_FOUND", /* 0x0138 */ + "NT_STATUS_ENTRYPOINT_NOT_FOUND", /* 0x0139 */ + "NT_STATUS_CONTROL_C_EXIT", /* 0x013a */ + "NT_STATUS_LOCAL_DISCONNECT", /* 0x013b */ + "NT_STATUS_REMOTE_DISCONNECT", /* 0x013c */ + "NT_STATUS_REMOTE_RESOURCES", /* 0x013d */ + "NT_STATUS_LINK_FAILED", /* 0x013e */ + "NT_STATUS_LINK_TIMEOUT", /* 0x013f */ + "NT_STATUS_INVALID_CONNECTION", /* 0x0140 */ + "NT_STATUS_INVALID_ADDRESS", /* 0x0141 */ + "NT_STATUS_DLL_INIT_FAILED", /* 0x0142 */ + "NT_STATUS_MISSING_SYSTEMFILE", /* 0x0143 */ + "NT_STATUS_UNHANDLED_EXCEPTION", /* 0x0144 */ + "NT_STATUS_APP_INIT_FAILURE", /* 0x0145 */ + "NT_STATUS_PAGEFILE_CREATE_FAILED", /* 0x0146 */ + "NT_STATUS_NO_PAGEFILE", /* 0x0147 */ + "NT_STATUS_INVALID_LEVEL", /* 0x0148 */ + "NT_STATUS_WRONG_PASSWORD_CORE", /* 0x0149 */ + "NT_STATUS_ILLEGAL_FLOAT_CONTEXT", /* 0x014a */ + "NT_STATUS_PIPE_BROKEN", /* 0x014b */ + "NT_STATUS_REGISTRY_CORRUPT", /* 0x014c */ + "NT_STATUS_REGISTRY_IO_FAILED", /* 0x014d */ + "NT_STATUS_NO_EVENT_PAIR", /* 0x014e */ + "NT_STATUS_UNRECOGNIZED_VOLUME", /* 0x014f */ + "NT_STATUS_SERIAL_NO_DEVICE_INITED", /* 0x0150 */ + "NT_STATUS_NO_SUCH_ALIAS", /* 0x0151 */ + "NT_STATUS_MEMBER_NOT_IN_ALIAS", /* 0x0152 */ + "NT_STATUS_MEMBER_IN_ALIAS", /* 0x0153 */ + "NT_STATUS_ALIAS_EXISTS", /* 0x0154 */ + "NT_STATUS_LOGON_NOT_GRANTED", /* 0x0155 */ + "NT_STATUS_TOO_MANY_SECRETS", /* 0x0156 */ + "NT_STATUS_SECRET_TOO_LONG", /* 0x0157 */ + "NT_STATUS_INTERNAL_DB_ERROR", /* 0x0158 */ + "NT_STATUS_FULLSCREEN_MODE", /* 0x0159 */ + "NT_STATUS_TOO_MANY_CONTEXT_IDS", /* 0x015a */ + "NT_STATUS_LOGON_TYPE_NOT_GRANTED", /* 0x015b */ + "NT_STATUS_NOT_REGISTRY_FILE", /* 0x015c */ + "NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED", /* 0x015d */ + "NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR", /* 0x015e */ + "NT_STATUS_FT_MISSING_MEMBER", /* 0x015f */ + "NT_STATUS_ILL_FORMED_SERVICE_ENTRY", /* 0x0160 */ + "NT_STATUS_ILLEGAL_CHARACTER", /* 0x0161 */ + "NT_STATUS_UNMAPPABLE_CHARACTER", /* 0x0162 */ + "NT_STATUS_UNDEFINED_CHARACTER", /* 0x0163 */ + "NT_STATUS_FLOPPY_VOLUME", /* 0x0164 */ + "NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND", /* 0x0165 */ + "NT_STATUS_FLOPPY_WRONG_CYLINDER", /* 0x0166 */ + "NT_STATUS_FLOPPY_UNKNOWN_ERROR", /* 0x0167 */ + "NT_STATUS_FLOPPY_BAD_REGISTERS", /* 0x0168 */ + "NT_STATUS_DISK_RECALIBRATE_FAILED", /* 0x0169 */ + "NT_STATUS_DISK_OPERATION_FAILED", /* 0x016a */ + "NT_STATUS_DISK_RESET_FAILED", /* 0x016b */ + "NT_STATUS_SHARED_IRQ_BUSY", /* 0x016c */ + "NT_STATUS_FT_ORPHANING", /* 0x016d */ + "NT_STATUS_PARTITION_FAILURE", /* 0x0172 */ + "NT_STATUS_INVALID_BLOCK_LENGTH", /* 0x0173 */ + "NT_STATUS_DEVICE_NOT_PARTITIONED", /* 0x0174 */ + "NT_STATUS_UNABLE_TO_LOCK_MEDIA", /* 0x0175 */ + "NT_STATUS_UNABLE_TO_UNLOAD_MEDIA", /* 0x0176 */ + "NT_STATUS_EOM_OVERFLOW", /* 0x0177 */ + "NT_STATUS_NO_MEDIA", /* 0x0178 */ + "NT_STATUS_NO_SUCH_MEMBER", /* 0x017a */ + "NT_STATUS_INVALID_MEMBER", /* 0x017b */ + "NT_STATUS_KEY_DELETED", /* 0x017c */ + "NT_STATUS_NO_LOG_SPACE", /* 0x017d */ + "NT_STATUS_TOO_MANY_SIDS", /* 0x017e */ + "NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED", /* 0x017f */ + "NT_STATUS_KEY_HAS_CHILDREN", /* 0x0180 */ + "NT_STATUS_CHILD_MUST_BE_VOLATILE", /* 0x0181 */ + "NT_STATUS_DEVICE_CONFIGURATION_ERROR", /* 0x0182 */ + "NT_STATUS_DRIVER_INTERNAL_ERROR", /* 0x0183 */ + "NT_STATUS_INVALID_DEVICE_STATE", /* 0x0184 */ + "NT_STATUS_IO_DEVICE_ERROR", /* 0x0185 */ + "NT_STATUS_DEVICE_PROTOCOL_ERROR", /* 0x0186 */ + "NT_STATUS_BACKUP_CONTROLLER", /* 0x0187 */ + "NT_STATUS_LOG_FILE_FULL", /* 0x0188 */ + "NT_STATUS_TOO_LATE", /* 0x0189 */ + "NT_STATUS_NO_TRUST_LSA_SECRET", /* 0x018a */ + "NT_STATUS_NO_TRUST_SAM_ACCOUNT", /* 0x018b */ + "NT_STATUS_TRUSTED_DOMAIN_FAILURE", /* 0x018c */ + "NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE", /* 0x018d */ + "NT_STATUS_EVENTLOG_FILE_CORRUPT", /* 0x018e */ + "NT_STATUS_EVENTLOG_CANT_START", /* 0x018f */ + "NT_STATUS_TRUST_FAILURE", /* 0x0190 */ + "NT_STATUS_MUTANT_LIMIT_EXCEEDED", /* 0x0191 */ + "NT_STATUS_NETLOGON_NOT_STARTED", /* 0x0192 */ + "NT_STATUS_ACCOUNT_EXPIRED", /* 0x0193 */ + "NT_STATUS_POSSIBLE_DEADLOCK", /* 0x0194 */ + "NT_STATUS_NETWORK_CREDENTIAL_CONFLICT", /* 0x0195 */ + "NT_STATUS_REMOTE_SESSION_LIMIT", /* 0x0196 */ + "NT_STATUS_EVENTLOG_FILE_CHANGED", /* 0x0197 */ + "NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT", /* 0x0198 */ + "NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT", /* 0x0199 */ + "NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT", /* 0x019a */ + "NT_STATUS_DOMAIN_TRUST_INCONSISTENT", /* 0x019b */ + "NT_STATUS_FS_DRIVER_REQUIRED", /* 0x019c */ + "NT_STATUS_NO_USER_SESSION_KEY", /* 0x0202 */ + "NT_STATUS_USER_SESSION_DELETED", /* 0x0203 */ + "NT_STATUS_RESOURCE_LANG_NOT_FOUND", /* 0x0204 */ + "NT_STATUS_INSUFF_SERVER_RESOURCES", /* 0x0205 */ + "NT_STATUS_INVALID_BUFFER_SIZE", /* 0x0206 */ + "NT_STATUS_INVALID_ADDRESS_COMPONENT", /* 0x0207 */ + "NT_STATUS_INVALID_ADDRESS_WILDCARD", /* 0x0208 */ + "NT_STATUS_TOO_MANY_ADDRESSES", /* 0x0209 */ + "NT_STATUS_ADDRESS_ALREADY_EXISTS", /* 0x020a */ + "NT_STATUS_ADDRESS_CLOSED", /* 0x020b */ + "NT_STATUS_CONNECTION_DISCONNECTED", /* 0x020c */ + "NT_STATUS_CONNECTION_RESET", /* 0x020d */ + "NT_STATUS_TOO_MANY_NODES", /* 0x020e */ + "NT_STATUS_TRANSACTION_ABORTED", /* 0x020f */ + "NT_STATUS_TRANSACTION_TIMED_OUT", /* 0x0210 */ + "NT_STATUS_TRANSACTION_NO_RELEASE", /* 0x0211 */ + "NT_STATUS_TRANSACTION_NO_MATCH", /* 0x0212 */ + "NT_STATUS_TRANSACTION_RESPONDED", /* 0x0213 */ + "NT_STATUS_TRANSACTION_INVALID_ID", /* 0x0214 */ + "NT_STATUS_TRANSACTION_INVALID_TYPE", /* 0x0215 */ + "NT_STATUS_NOT_SERVER_SESSION", /* 0x0216 */ + "NT_STATUS_NOT_CLIENT_SESSION", /* 0x0217 */ + "NT_STATUS_CANNOT_LOAD_REGISTRY_FILE", /* 0x0218 */ + "NT_STATUS_DEBUG_ATTACH_FAILED", /* 0x0219 */ + "NT_STATUS_SYSTEM_PROCESS_TERMINATED", /* 0x021a */ + "NT_STATUS_DATA_NOT_ACCEPTED", /* 0x021b */ + "NT_STATUS_NO_BROWSER_SERVERS_FOUND", /* 0x021c */ + "NT_STATUS_VDM_HARD_ERROR", /* 0x021d */ + "NT_STATUS_DRIVER_CANCEL_TIMEOUT", /* 0x021e */ + "NT_STATUS_REPLY_MESSAGE_MISMATCH", /* 0x021f */ + "NT_STATUS_MAPPED_ALIGNMENT", /* 0x0220 */ + "NT_STATUS_IMAGE_CHECKSUM_MISMATCH", /* 0x0221 */ + "NT_STATUS_LOST_WRITEBEHIND_DATA", /* 0x0222 */ + "NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID", /* 0x0223 */ + "NT_STATUS_PASSWORD_MUST_CHANGE", /* 0x0224 */ + "NT_STATUS_NOT_FOUND", /* 0x0225 */ + "NT_STATUS_NOT_TINY_STREAM", /* 0x0226 */ + "NT_STATUS_RECOVERY_FAILURE", /* 0x0227 */ + "NT_STATUS_STACK_OVERFLOW_READ", /* 0x0228 */ + "NT_STATUS_FAIL_CHECK", /* 0x0229 */ + "NT_STATUS_DUPLICATE_OBJECTID", /* 0x022a */ + "NT_STATUS_OBJECTID_EXISTS", /* 0x022b */ + "NT_STATUS_CONVERT_TO_LARGE", /* 0x022c */ + "NT_STATUS_RETRY", /* 0x022d */ + "NT_STATUS_FOUND_OUT_OF_SCOPE", /* 0x022e */ + "NT_STATUS_ALLOCATE_BUCKET", /* 0x022f */ + "NT_STATUS_PROPSET_NOT_FOUND", /* 0x0230 */ + "NT_STATUS_MARSHALL_OVERFLOW", /* 0x0231 */ + "NT_STATUS_INVALID_VARIANT", /* 0x0232 */ + "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND", /* 0x0233 */ + "NT_STATUS_ACCOUNT_LOCKED_OUT", /* 0x0234 */ + "NT_STATUS_HANDLE_NOT_CLOSABLE", /* 0x0235 */ + "NT_STATUS_CONNECTION_REFUSED", /* 0x0236 */ + "NT_STATUS_GRACEFUL_DISCONNECT", /* 0x0237 */ + "NT_STATUS_ADDRESS_ALREADY_ASSOCIATED", /* 0x0238 */ + "NT_STATUS_ADDRESS_NOT_ASSOCIATED", /* 0x0239 */ + "NT_STATUS_CONNECTION_INVALID", /* 0x023a */ + "NT_STATUS_CONNECTION_ACTIVE", /* 0x023b */ + "NT_STATUS_NETWORK_UNREACHABLE", /* 0x023c */ + "NT_STATUS_HOST_UNREACHABLE", /* 0x023d */ + "NT_STATUS_PROTOCOL_UNREACHABLE", /* 0x023e */ + "NT_STATUS_PORT_UNREACHABLE", /* 0x023f */ + "NT_STATUS_REQUEST_ABORTED", /* 0x0240 */ + "NT_STATUS_CONNECTION_ABORTED", /* 0x0241 */ + "NT_STATUS_BAD_COMPRESSION_BUFFER", /* 0x0242 */ + "NT_STATUS_USER_MAPPED_FILE", /* 0x0243 */ + "NT_STATUS_AUDIT_FAILED", /* 0x0244 */ + "NT_STATUS_TIMER_RESOLUTION_NOT_SET", /* 0x0245 */ + "NT_STATUS_CONNECTION_COUNT_LIMIT", /* 0x0246 */ + "NT_STATUS_LOGIN_TIME_RESTRICTION", /* 0x0247 */ + "NT_STATUS_LOGIN_WKSTA_RESTRICTION", /* 0x0248 */ + "NT_STATUS_IMAGE_MP_UP_MISMATCH", /* 0x0249 */ + "NT_STATUS_INSUFFICIENT_LOGON_INFO", /* 0x0250 */ + "NT_STATUS_BAD_DLL_ENTRYPOINT", /* 0x0251 */ + "NT_STATUS_BAD_SERVICE_ENTRYPOINT", /* 0x0252 */ + "NT_STATUS_LPC_REPLY_LOST", /* 0x0253 */ + "NT_STATUS_IP_ADDRESS_CONFLICT1", /* 0x0254 */ + "NT_STATUS_IP_ADDRESS_CONFLICT2", /* 0x0255 */ + "NT_STATUS_REGISTRY_QUOTA_LIMIT", /* 0x0256 */ + "NT_STATUS_PATH_NOT_COVERED", /* 0x0257 */ + "NT_STATUS_NO_CALLBACK_ACTIVE", /* 0x0258 */ + "NT_STATUS_LICENSE_QUOTA_EXCEEDED", /* 0x0259 */ + "NT_STATUS_PWD_TOO_SHORT", /* 0x025a */ + "NT_STATUS_PWD_TOO_RECENT", /* 0x025b */ + "NT_STATUS_PWD_HISTORY_CONFLICT", /* 0x025c */ + "NT_STATUS_PLUGPLAY_NO_DEVICE", /* 0x025e */ + "NT_STATUS_UNSUPPORTED_COMPRESSION", /* 0x025f */ + "NT_STATUS_INVALID_HW_PROFILE", /* 0x0260 */ + "NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH", /* 0x0261 */ + "NT_STATUS_DRIVER_ORDINAL_NOT_FOUND", /* 0x0262 */ + "NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND", /* 0x0263 */ + "NT_STATUS_RESOURCE_NOT_OWNED", /* 0x0264 */ + "NT_STATUS_TOO_MANY_LINKS", /* 0x0265 */ + "NT_STATUS_QUOTA_LIST_INCONSISTENT", /* 0x0266 */ + "NT_STATUS_FILE_IS_OFFLINE" /* 0x0267 */ +}; + +#define NT_STATUS(a) nt_status_to_string[a & 0x3FFFFFFF] + +struct Packet +{ + size_t frame; + + uint8_t magic[4]; + + bool valid_smb() { + return !memcmp(smb_hdr.magic, magic, 4); + } + + Packet(const uint8_t *data, size_t size) : + ip_hdr(data + 14, size - 14), + tcp_hdr(data + 14 + ip_hdr.header_length, + size - 14 - ip_hdr.header_length), + smb_hdr(data + 14 + ip_hdr.header_length + tcp_hdr.length, + size - 14 - ip_hdr.header_length - tcp_hdr.length) + { + const uint8_t da[] = { 0xFF, 'S', 'M', 'B' }; + + memcpy(magic, da, sizeof(da)); + + if (valid_smb()) { + size_t len = 14 + ip_hdr.header_length + tcp_hdr.length + 36; + + switch (smb_hdr.command) { + case NtCreateAndXRequest::COMMAND: + if (smb_hdr.flags & 0x80) { + ntcreate_resp = NtCreateAndXResponse(data+len, size - len); + } else { + ntcreate_req = NtCreateAndXRequest(data + len, size - len); + } + break; + case ReadAndXRequest::COMMAND: + if (!(smb_hdr.flags & 0x80)) { + read_req = ReadAndXRequest(data + len, size - len); + } + break; + case WriteAndXRequest::COMMAND: + if (!(smb_hdr.flags & 0x80)) { + write_req = WriteAndXRequest(data + len, size - len); + } + break; + case CloseRequest::COMMAND: + if (!(smb_hdr.flags & 0x80)) { + close_req = CloseRequest(data + len, size - len); + } + break; + } + } + } + + ip ip_hdr; + tcp tcp_hdr; + smb smb_hdr; + + NtCreateAndXRequest ntcreate_req; + NtCreateAndXResponse ntcreate_resp; + ReadAndXRequest read_req; + WriteAndXRequest write_req; + CloseRequest close_req; +}; + +int main(int argc, char **argv) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + pcap_t *cap; + struct pcap_pkthdr *pkt_hdr; + const uint8_t *data; + + static struct option long_opts[] = { + { "show-files", 0, 0, 's' }, + { "drop-incomplete-sessions", 0, 0, 'i' }, + { 0, 0, 0, 0 } + }; + const char *short_opts = "si"; + int opt_ind; + char ch; + int show_files = 0; + int drop_incomplete_sessions = 0; + + while ((ch = getopt_long(argc,argv,short_opts,long_opts,&opt_ind)) != -1) { + switch (ch) { + case 's': + show_files = 1; + break; + case 'i': + drop_incomplete_sessions = 1; + break; + default: + break; + } + } + + if ((argc - optind) != 1) { + std::cout << "Usage: " << argv[0] << " [OPTIONS] FILE" << std::endl; + exit(1); + } + + cap = pcap_open_offline(argv[optind], errbuf); + + if (!cap) { + std::cout << "pcap_open_offline(" << argv[optind] << "): " << errbuf + << std::endl; + exit(1); + } + + std::vector<Packet> packets; + size_t frame = 0; + std::set<uint16_t> current_fids; + + while (1 == pcap_next_ex(cap, &pkt_hdr, &data)) { + Packet packet(data, pkt_hdr->len); + + ++frame; + + if (packet.valid_smb()) { + packet.frame = frame; + packets.push_back(packet); + } + } + + pcap_close(cap); + + for (std::vector<Packet>::iterator i = packets.begin(); + i != packets.end(); ++i) { + if (!(i->smb_hdr.flags & 0x80)) { + /* we have a request */ + std::vector<Packet>::iterator j; + + /* look ahead for the response */ + for (j = i; j != packets.end(); ++j) { + if (j->smb_hdr.flags & 0x80 && // response + j->smb_hdr.command == i->smb_hdr.command && + j->smb_hdr.tid == i->smb_hdr.tid && + j->smb_hdr.pid == i->smb_hdr.pid && + j->smb_hdr.uid == i->smb_hdr.uid && + j->smb_hdr.mid == i->smb_hdr.mid) { + break; + } + } + + /* no response? guess we can't display this command */ + if (j == packets.end()) continue; + + size_t len; + + switch (i->smb_hdr.command) { + case NtCreateAndXRequest::COMMAND: + std::cout << "NTCreateX \"" << i->ntcreate_req.file_name << "\" " + << i->ntcreate_req.create_options << " " + << i->ntcreate_req.disposition << " " + << j->ntcreate_resp.fid << " " + << NT_STATUS(j->smb_hdr.nt_status) << std::endl; + current_fids.insert(j->ntcreate_resp.fid); + break; + case ReadAndXRequest::COMMAND: + len = i->read_req.max_count_high * 64 * 1024 + + i->read_req.max_count_low; + + if (!drop_incomplete_sessions || current_fids.count(i->read_req.fid)) { + std::cout << "ReadX " << i->read_req.fid << " " + << i->read_req.offset << " " + << len << " " << len << " " + << NT_STATUS(j->smb_hdr.nt_status) << std::endl; + } + break; + case WriteAndXRequest::COMMAND: + len = i->write_req.data_length_hi * 64 * 1024 + + i->write_req.data_length_lo; + + if (!drop_incomplete_sessions||current_fids.count(i->write_req.fid)) { + std::cout << "WriteX " << i->write_req.fid << " " + << i->write_req.offset << " " + << len << " " << len << " " + << NT_STATUS(j->smb_hdr.nt_status) << std::endl; + } + break; + case CloseRequest::COMMAND: + if (!drop_incomplete_sessions||current_fids.count(i->close_req.fid)) { + std::cout << "Close " << i->close_req.fid << " " + << NT_STATUS(j->smb_hdr.nt_status) << std::endl; + } + current_fids.erase(i->close_req.fid); + break; + } + } + } + + return 0; +} diff --git a/examples/pcap2nbench/ntcreateandxrequest.cpp b/examples/pcap2nbench/ntcreateandxrequest.cpp new file mode 100644 index 0000000000..5efc256c61 --- /dev/null +++ b/examples/pcap2nbench/ntcreateandxrequest.cpp @@ -0,0 +1,73 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#include <netinet/in.h> + +#include "ntcreateandxrequest.hpp" + +NtCreateAndXRequest::NtCreateAndXRequest(const uint8_t *data, size_t size) +{ + if (size < 52) { + std::cerr << "Invalid NtCreateAndX Request" << std::endl; + return; + } + + word_count = data[0]; + and_x_command = data[1]; + reserved = data[2]; + memcpy(&and_x_offset, data + 3, 2); + reserved1 = data[5]; + memcpy(&file_name_len, data + 6, 2); + memcpy(&create_flags, data + 8, 4); + memcpy(&root_fid, data + 12, 4); + memcpy(&access_mask, data + 16, 4); + memcpy(&allocation_size, data + 20, 8); + memcpy(&file_attributes, data + 28, 4); + memcpy(&share_access, data + 32, 4); + memcpy(&disposition, data + 36, 4); + memcpy(&create_options, data + 40, 4); + memcpy(&impersonation, data + 44, 4); + security_flags = data[48]; + memcpy(&byte_count, data + 49, 2); + file_name = (const char *)(data + 51); +} + +std::ostream &operator<<(std::ostream &lhs, const NtCreateAndXRequest &rhs) +{ + lhs << "Word Count: " << (uint16_t)rhs.word_count << std::endl + << "AndXCommand: " << (uint16_t)rhs.and_x_command << std::endl + << "Reserved: " << (uint16_t)rhs.reserved << std::endl + << "AndXOffset: " << rhs.and_x_offset << std::endl + << "Reserved: " << (uint16_t)rhs.reserved1 << std::endl + << "File Name Len: " << rhs.file_name_len << std::endl + << "Create Flags: " << rhs.create_flags << std::endl + << "Root FID: " << rhs.root_fid << std::endl + << "Access Mask: " << rhs.access_mask << std::endl + << "Allocation Size: " << rhs.allocation_size << std::endl + << "File Attributes: " << rhs.file_attributes << std::endl + << "Share Access: " << rhs.share_access << std::endl + << "Disposition: " << rhs.disposition << std::endl + << "Create Options: " << rhs.create_options << std::endl + << "Impersonation: " << rhs.impersonation << std::endl + << "Security Flags: " << (uint16_t)rhs.security_flags << std::endl + << "Byte Count: " << rhs.byte_count << std::endl + << "File Name: " << rhs.file_name << std::endl; + return lhs; +} diff --git a/examples/pcap2nbench/ntcreateandxrequest.hpp b/examples/pcap2nbench/ntcreateandxrequest.hpp new file mode 100644 index 0000000000..07c19fdc8a --- /dev/null +++ b/examples/pcap2nbench/ntcreateandxrequest.hpp @@ -0,0 +1,57 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#ifndef _NT_CREATE_AND_X_REQUEST_HPP +#define _NT_CREATE_AND_X_REQUEST_HPP + +#include <iostream> +#include <stdint.h> + +struct NtCreateAndXRequest { + enum { + COMMAND = 0xa2 + }; + + NtCreateAndXRequest() { } + NtCreateAndXRequest(const uint8_t *data, size_t size); + + uint8_t word_count; + uint8_t and_x_command; + uint8_t reserved; + uint16_t and_x_offset; + uint8_t reserved1; + uint16_t file_name_len; + uint32_t create_flags; + uint32_t root_fid; + uint32_t access_mask; + uint64_t allocation_size; + uint32_t file_attributes; + uint32_t share_access; + uint32_t disposition; + uint32_t create_options; + uint32_t impersonation; + uint8_t security_flags; + uint16_t byte_count; + std::string file_name; +}; + +std::ostream &operator<<(std::ostream &lhs, const NtCreateAndXRequest &rhs); + +#endif diff --git a/examples/pcap2nbench/ntcreateandxresponse.cpp b/examples/pcap2nbench/ntcreateandxresponse.cpp new file mode 100644 index 0000000000..7e427b9716 --- /dev/null +++ b/examples/pcap2nbench/ntcreateandxresponse.cpp @@ -0,0 +1,42 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#include <netinet/in.h> + +#include "ntcreateandxresponse.hpp" + +NtCreateAndXResponse::NtCreateAndXResponse(const uint8_t *data, size_t size) +{ + if (size < 71) { + return; + } + + word_count = data[0]; + and_x_command = data[1]; + reserved = data[2]; + memcpy(&and_x_offset, data + 3, 2); + oplock_level = data[5]; + memcpy(&fid, data + 6, 2); +} + +std::ostream &operator<<(std::ostream &lhs, const NtCreateAndXResponse &rhs) +{ + return lhs; +} diff --git a/examples/pcap2nbench/ntcreateandxresponse.hpp b/examples/pcap2nbench/ntcreateandxresponse.hpp new file mode 100644 index 0000000000..c17ff21f55 --- /dev/null +++ b/examples/pcap2nbench/ntcreateandxresponse.hpp @@ -0,0 +1,57 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#ifndef _NT_CREATE_AND_X_RESPONSE_HPP +#define _NT_CREATE_AND_X_RESPONSE_HPP + +#include <iostream> +#include <stdint.h> + +struct NtCreateAndXResponse { + enum { + COMMAND = 0xa2 + }; + + NtCreateAndXResponse() {} + NtCreateAndXResponse(const uint8_t *data, size_t size); + + uint8_t word_count; + uint8_t and_x_command; + uint8_t reserved; + uint16_t and_x_offset; + uint8_t oplock_level; + uint16_t fid; + uint32_t create_action; + uint64_t create_date; + uint64_t access_date; + uint64_t write_date; + uint64_t change_date; + uint32_t file_attributes; + uint64_t allocation_size; + uint64_t end_of_file; + uint16_t file_type; + uint16_t ipc_state; + uint8_t is_directory; + uint16_t byte_count; +}; + +std::ostream &operator<<(std::ostream &lhs, const NtCreateAndXResponse &rhs); + +#endif diff --git a/examples/pcap2nbench/readandxrequest.cpp b/examples/pcap2nbench/readandxrequest.cpp new file mode 100644 index 0000000000..87411fc0c9 --- /dev/null +++ b/examples/pcap2nbench/readandxrequest.cpp @@ -0,0 +1,60 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#include <netinet/in.h> + +#include "readandxrequest.hpp" + +ReadAndXRequest::ReadAndXRequest(const uint8_t *data, size_t size) +{ + if (size < 27) { + std::cerr << "Invalid ReadAndX Request" << std::endl; + return; + } + word_count = data[0]; + and_x_command = data[1]; + reserved = data[2]; + memcpy(&and_x_offset, data + 3, 2); + memcpy(&fid, data + 5, 2); + memcpy(&offset, data + 7, 4); + memcpy(&max_count_low, data + 11, 2); + memcpy(&min_count, data + 13, 2); + memcpy(&max_count_high, data + 15, 4); + memcpy(&remaining, data + 19, 2); + memcpy(&high_offset, data + 21, 4); + memcpy(&byte_count, data + 25, 2); +} + +std::ostream &operator<<(std::ostream &lhs, const ReadAndXRequest &rhs) +{ + lhs << "Word Count: " << (uint16_t)rhs.word_count << std::endl + << "AndXCommand: " << (uint16_t)rhs.and_x_command << std::endl + << "Reserved: " << (uint16_t)rhs.reserved << std::endl + << "AndX Offset: " << rhs.and_x_offset << std::endl + << "Fid: " << rhs.fid << std::endl + << "Offset: " << rhs.offset << std::endl + << "Max Count Low: " << rhs.max_count_low << std::endl + << "Min Count: " << rhs.min_count << std::endl + << "Max Count High: " << rhs.max_count_high << std::endl + << "Remaining: " << rhs.remaining << std::endl + << "High Offset: " << rhs.high_offset << std::endl + << "Byte Count: " << rhs.byte_count << std::endl; + return lhs; +} diff --git a/examples/pcap2nbench/readandxrequest.hpp b/examples/pcap2nbench/readandxrequest.hpp new file mode 100644 index 0000000000..21e0bca3b3 --- /dev/null +++ b/examples/pcap2nbench/readandxrequest.hpp @@ -0,0 +1,51 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#ifndef _READ_AND_X_REQUEST_HPP +#define _READ_AND_X_REQUEST_HPP + +#include <iostream> +#include <stdint.h> + +struct ReadAndXRequest { + enum { + COMMAND = 0x2e + }; + + ReadAndXRequest() {} + ReadAndXRequest(const uint8_t *data, size_t size); + + uint8_t word_count; + uint8_t and_x_command; + uint8_t reserved; + uint16_t and_x_offset; + uint16_t fid; + uint32_t offset; + uint16_t max_count_low; + uint16_t min_count; + uint32_t max_count_high; + uint16_t remaining; + uint32_t high_offset; + uint16_t byte_count; +}; + +std::ostream &operator<<(std::ostream &lhs, const ReadAndXRequest &rhs); + +#endif diff --git a/examples/pcap2nbench/readandxresponse.hpp b/examples/pcap2nbench/readandxresponse.hpp new file mode 100644 index 0000000000..0a302cb657 --- /dev/null +++ b/examples/pcap2nbench/readandxresponse.hpp @@ -0,0 +1,47 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#ifndef _READ_AND_X_RESPONSE_HPP +#define _READ_AND_X_RESPONSE_HPP + +class ReadAndXResponse { + ReadAndXReponse(const uint8_t *data, size_t size); + + uint8_t word_count; + uint8_t and_x_command; + uint8_t reserved; + uint16_t and_x_offset; + uint8_t oplock_level; + uint16_t fid; + uint32_t create_action; + uint64_t created_date; + uint64_t access_date; + uint64_t write_date; + uint64_t change_date; + uint32_t file_attributes; + uint64_t allocation_size; + uint64_t end_of_file; + uint16_t file_type; + uint16_t ipc_state; + uint8_t is_directory; + uint16_t byte_count; +}; + +#endif diff --git a/examples/pcap2nbench/smb.cpp b/examples/pcap2nbench/smb.cpp new file mode 100644 index 0000000000..78f8aaf23a --- /dev/null +++ b/examples/pcap2nbench/smb.cpp @@ -0,0 +1,71 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#include <netinet/in.h> + +#include "smb.hpp" + +smb::smb(const uint8_t *data, size_t length) +{ + if (length < 36) { + memset(magic, 0, 4); + return; + } + + /* This code assumes Little Endian... Don't say I didn't warn you */ + memcpy(&size, data + 2, 2); + memcpy(magic, data + 4, 4); + + command = data[8]; + + memcpy(&nt_status, data + 9, 4); + + flags = data[13]; + + memcpy(&flags2, data + 14, 2); + memcpy(&pid_hi, data + 16, 2); + memcpy(signature, data + 18, 8); + memcpy(&reserved, data + 26, 2); + memcpy(&tid, data + 28, 2); + memcpy(&pid, data + 30, 2); + memcpy(&uid, data + 32, 2); + memcpy(&mid, data + 34, 2); +} + +std::ostream &operator<<(std::ostream &lhs, const smb &rhs) +{ + lhs << "Magic: "; + for (int i = 1; i < 4; i++) { + lhs << rhs.magic[i]; + } + lhs << std::endl; + + lhs << "Command: " << (uint16_t)rhs.command << std::endl + << "NT Status: " << rhs.nt_status << std::endl + << "Flags: " << (uint16_t)rhs.flags << std::endl + << "Flags2: " << rhs.flags2 << std::endl + << "Pid Hi: " << rhs.pid_hi << std::endl + << "Tid: " << rhs.tid << std::endl + << "Pid: " << rhs.pid << std::endl + << "Uid: " << rhs.uid << std::endl + << "Mid: " << rhs.mid << std::endl; + + return lhs; +} diff --git a/examples/pcap2nbench/smb.hpp b/examples/pcap2nbench/smb.hpp new file mode 100644 index 0000000000..79a7f8c415 --- /dev/null +++ b/examples/pcap2nbench/smb.hpp @@ -0,0 +1,48 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#ifndef _SMB_HPP +#define _SMB_HPP + +#include <iostream> +#include <stdint.h> + +struct smb { + smb(const uint8_t *data, size_t length); + + uint16_t size; + + uint8_t magic[4]; /* 0xff, 'S', 'M', 'B' */ + uint8_t command; + uint32_t nt_status; + uint8_t flags; + uint16_t flags2; + uint16_t pid_hi; + uint8_t signature[8]; + uint16_t reserved; + uint16_t tid; + uint16_t pid; + uint16_t uid; + uint16_t mid; +}; + +std::ostream &operator<<(std::ostream &lhs, const smb &rhs); + +#endif diff --git a/examples/pcap2nbench/tcp.cpp b/examples/pcap2nbench/tcp.cpp new file mode 100644 index 0000000000..8b5106011a --- /dev/null +++ b/examples/pcap2nbench/tcp.cpp @@ -0,0 +1,59 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#include <netinet/in.h> + +#include "tcp.hpp" + +tcp::tcp(const uint8_t *data, size_t size) +{ + if (size < 18) { + std::cerr << "Invalid TCP header" << std::endl; + } + + memcpy(&src_port, data, 2); + src_port = ntohs(src_port); + memcpy(&dst_port, data + 2, 2); + dst_port = ntohs(dst_port); + memcpy(&seq_number, data + 4, 4); + seq_number = ntohl(seq_number); + memcpy(&ack_number, data + 8, 4); + ack_number = ntohl(ack_number); + length = ((data[12] & 0xF0) >> 4) * 4; + flags = ((data[12] & 0x0F) << 8) | data[13]; + memcpy(&window_size, data + 14, 2); + window_size = ntohs(window_size); + memcpy(&checksum, data + 16, 2); + checksum = ntohs(checksum); +} + +std::ostream &operator<<(std::ostream &lhs, const tcp &rhs) +{ + lhs << "Source Port: " << rhs.src_port << std::endl + << "Destination Port: " << rhs.dst_port << std::endl + << "Sequence Number: " << rhs.seq_number << std::endl + << "Ack Number: " << rhs.ack_number << std::endl + << "Length: " << (uint16_t)(rhs.length) << std::endl + << "Flags: " << rhs.flags << std::endl + << "Window Size: " << rhs.window_size << std::endl + << "Checksum: " << rhs.checksum << std::endl; + + return lhs; +} diff --git a/examples/pcap2nbench/tcp.hpp b/examples/pcap2nbench/tcp.hpp new file mode 100644 index 0000000000..5eb7aaaa66 --- /dev/null +++ b/examples/pcap2nbench/tcp.hpp @@ -0,0 +1,42 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#ifndef _TCP_HPP +#define _TCP_HPP + +#include <iostream> +#include <stdint.h> + +struct tcp { + tcp(const uint8_t *data, size_t length); + + uint16_t src_port; + uint16_t dst_port; + uint32_t seq_number; + uint32_t ack_number; + uint8_t length; + uint16_t flags; + uint16_t window_size; + uint16_t checksum; +}; + +std::ostream &operator<<(std::ostream &lhs, const tcp &rhs); + +#endif diff --git a/examples/pcap2nbench/writeandxrequest.cpp b/examples/pcap2nbench/writeandxrequest.cpp new file mode 100644 index 0000000000..f56a03168c --- /dev/null +++ b/examples/pcap2nbench/writeandxrequest.cpp @@ -0,0 +1,65 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#include <netinet/in.h> + +#include "writeandxrequest.hpp" + +WriteAndXRequest::WriteAndXRequest(const uint8_t *data, size_t size) +{ + if (size < 31) { + std::cerr << "Invalid WriteAndX Request" << std::endl; + return; + } + word_count = data[0]; + and_x_command = data[1]; + reserved = data[2]; + memcpy(&and_x_offset, data + 3, 2); + memcpy(&fid, data + 5, 2); + memcpy(&offset, data + 7, 4); + memcpy(&reserved1, data + 11, 4); + memcpy(&write_mode, data + 15, 2); + memcpy(&remaining, data + 17, 2); + memcpy(&data_length_hi, data + 19, 2); + memcpy(&data_length_lo, data + 21, 2); + memcpy(&data_offset, data + 23, 2); + memcpy(&high_offset, data + 25, 4); + memcpy(&byte_count, data + 29, 2); + +} + +std::ostream &operator<<(std::ostream &lhs, const WriteAndXRequest &rhs) +{ + lhs << "Word Count: " << (uint16_t)rhs.word_count << std::endl + << "AndXCommand: " << (uint16_t)rhs.and_x_command << std::endl + << "Reserved: " << (uint16_t)rhs.reserved << std::endl + << "AndX Offset: " << rhs.and_x_offset << std::endl + << "Fid: " << rhs.fid << std::endl + << "Offset: " << rhs.offset << std::endl + << "Reserved: " << rhs.reserved1 << std::endl + << "Write Mode: " << rhs.write_mode << std::endl + << "Remaining: " << rhs.remaining << std::endl + << "Data Length Hi: " << rhs.data_length_hi << std::endl + << "Data Length Lo: " << rhs.data_length_lo << std::endl + << "Data Offset: " << rhs.data_offset << std::endl + << "High Offset: " << rhs.high_offset << std::endl + << "Byte Count: " << rhs.byte_count << std::endl; + return lhs; +} diff --git a/examples/pcap2nbench/writeandxrequest.hpp b/examples/pcap2nbench/writeandxrequest.hpp new file mode 100644 index 0000000000..c91bcc3b14 --- /dev/null +++ b/examples/pcap2nbench/writeandxrequest.hpp @@ -0,0 +1,53 @@ +/*\ + * pcap2nbench - Converts libpcap network traces to nbench input + * Copyright (C) 2004 Jim McDonough <jmcd@us.ibm.com> + * + * 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/>. + * + * Written by Anthony Liguori <aliguori@us.ibm.com> +\*/ + +#ifndef _WRITE_AND_X_REQUEST_HPP +#define _WRITE_AND_X_REQUEST_HPP + +#include <iostream> +#include <stdint.h> + +struct WriteAndXRequest { + enum { + COMMAND = 0x2f + }; + + WriteAndXRequest() {} + WriteAndXRequest(const uint8_t *data, size_t size); + + uint8_t word_count; + uint8_t and_x_command; + uint8_t reserved; + uint16_t and_x_offset; + uint16_t fid; + uint32_t offset; + uint32_t reserved1; + uint16_t write_mode; + uint16_t remaining; + uint16_t data_length_hi; + uint16_t data_length_lo; + uint16_t data_offset; + uint32_t high_offset; + uint16_t byte_count; +}; + +std::ostream &operator<<(std::ostream &lhs, const WriteAndXRequest &rhs); + +#endif diff --git a/examples/pdb/Makefile b/examples/pdb/Makefile new file mode 100644 index 0000000000..09d901d374 --- /dev/null +++ b/examples/pdb/Makefile @@ -0,0 +1,31 @@ +# Makefile for samba-pdb examples +# Variables + +CC = gcc +LIBTOOL = libtool + +SAMBA_SRC = ../../source +SAMBA_INCL = ../../source/include +UBIQX_SRC = ../../source/ubiqx +SMBWR_SRC = ../../source/smbwrapper +CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g -I/usr/include/heimdal -fPIC +PDB_OBJS = test.la + +# Default target + +default: $(PDB_OBJS) + +# Pattern rules + +%.la: %.lo + $(LIBTOOL) --mode=link $(CC) -module -o $@ $< $(LDFLAGS) -rpath /usr/lib/samba/pdb/ + +%.lo: %.c + $(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) -c $< + +# Misc targets + +clean: + rm -rf .libs + rm -f core *~ *% *.bak \ + $(PDB_OBJS) $(PDB_OBJS:.la=.o) $(PDB_OBJS:.la=.lo) diff --git a/examples/pdb/README b/examples/pdb/README new file mode 100644 index 0000000000..692d32225d --- /dev/null +++ b/examples/pdb/README @@ -0,0 +1,20 @@ +README for Samba Password Database (PDB) examples +==================================================== +Jelmer Vernooij <jelmer@nl.linux.org> +Stefan (metze) Metzmacher <metze@samba.org> + +The test.c file in this directory contains a very basic example of +a pdb plugin. It just prints the name of the function that is executed using +DEBUG. Maybe it's nice to include some of the arguments to the function in the +future too.. + +To debug passdb backends, try to run gdb on the 'pdbedit' executable. That's +really much easier than restarting smbd constantly and attaching with your +debugger. + +New passdb plugins should go into the samba lib directory, (/usr/lib/samba/pdb/ +for most distributions). An example would be: /usr/lib/samba/pdb/test.so + +Be aware that the SQL and XML based passdb modules have been removed since the +3.0.23 release. More information of external support for SQL passdb modules +can be found at http://pdbsql.sourceforge.net/. diff --git a/examples/pdb/test.c b/examples/pdb/test.c new file mode 100644 index 0000000000..b5ddefc480 --- /dev/null +++ b/examples/pdb/test.c @@ -0,0 +1,144 @@ +/* + * Test password backend for samba + * Copyright (C) Jelmer Vernooij 2002 + * + * 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/>. + */ + + +#include "includes.h" + +static int testsam_debug_level = DBGC_ALL; + +#undef DBGC_CLASS +#define DBGC_CLASS testsam_debug_level + +/*************************************************************** + Start enumeration of the passwd list. +****************************************************************/ + +static NTSTATUS testsam_setsampwent(struct pdb_methods *methods, BOOL update, uint32 acb_mask) +{ + DEBUG(10, ("testsam_setsampwent called\n")); + return NT_STATUS_NOT_IMPLEMENTED; +} + +/*************************************************************** + End enumeration of the passwd list. +****************************************************************/ + +static void testsam_endsampwent(struct pdb_methods *methods) +{ + DEBUG(10, ("testsam_endsampwent called\n")); +} + +/***************************************************************** + Get one struct samu from the list (next in line) +*****************************************************************/ + +static NTSTATUS testsam_getsampwent(struct pdb_methods *methods, struct samu *user) +{ + DEBUG(10, ("testsam_getsampwent called\n")); + return NT_STATUS_NOT_IMPLEMENTED; +} + +/****************************************************************** + Lookup a name in the SAM database +******************************************************************/ + +static NTSTATUS testsam_getsampwnam (struct pdb_methods *methods, struct samu *user, const char *sname) +{ + DEBUG(10, ("testsam_getsampwnam called\n")); + return NT_STATUS_NOT_IMPLEMENTED; +} + +/*************************************************************************** + Search by sid + **************************************************************************/ + +static NTSTATUS testsam_getsampwsid (struct pdb_methods *methods, struct samu *user, const DOM_SID *sid) +{ + DEBUG(10, ("testsam_getsampwsid called\n")); + return NT_STATUS_NOT_IMPLEMENTED; +} + +/*************************************************************************** + Delete a struct samu +****************************************************************************/ + +static NTSTATUS testsam_delete_sam_account(struct pdb_methods *methods, struct samu *sam_pass) +{ + DEBUG(10, ("testsam_delete_sam_account called\n")); + return NT_STATUS_NOT_IMPLEMENTED; +} + +/*************************************************************************** + Modifies an existing struct samu +****************************************************************************/ + +static NTSTATUS testsam_update_sam_account (struct pdb_methods *methods, struct samu *newpwd) +{ + DEBUG(10, ("testsam_update_sam_account called\n")); + return NT_STATUS_NOT_IMPLEMENTED; +} + +/*************************************************************************** + Adds an existing struct samu +****************************************************************************/ + +static NTSTATUS testsam_add_sam_account (struct pdb_methods *methods, struct samu *newpwd) +{ + DEBUG(10, ("testsam_add_sam_account called\n")); + return NT_STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS testsam_init(struct pdb_methods **pdb_method, const char *location) +{ + NTSTATUS nt_status; + + if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) { + return nt_status; + } + + (*pdb_method)->name = "testsam"; + + /* Functions your pdb module doesn't provide should not be + set, make_pdb_methods() already provide suitable defaults for missing functions */ + + (*pdb_method)->setsampwent = testsam_setsampwent; + (*pdb_method)->endsampwent = testsam_endsampwent; + (*pdb_method)->getsampwent = testsam_getsampwent; + (*pdb_method)->getsampwnam = testsam_getsampwnam; + (*pdb_method)->getsampwsid = testsam_getsampwsid; + (*pdb_method)->add_sam_account = testsam_add_sam_account; + (*pdb_method)->update_sam_account = testsam_update_sam_account; + (*pdb_method)->delete_sam_account = testsam_delete_sam_account; + + testsam_debug_level = debug_add_class("testsam"); + if (testsam_debug_level == -1) { + testsam_debug_level = DBGC_ALL; + DEBUG(0, ("testsam: Couldn't register custom debugging class!\n")); + } else DEBUG(0, ("testsam: Debug class number of 'testsam': %d\n", testsam_debug_level)); + + DEBUG(0, ("Initializing testsam\n")); + if (location) + DEBUG(10, ("Location: %s\n", location)); + + return NT_STATUS_OK; +} + +NTSTATUS init_module(void) { + return smb_register_passdb(PASSDB_INTERFACE_VERSION, "testsam", + testsam_init); +} diff --git a/examples/perfcounter/Makefile b/examples/perfcounter/Makefile new file mode 100644 index 0000000000..925e2ea080 --- /dev/null +++ b/examples/perfcounter/Makefile @@ -0,0 +1,38 @@ +# +# Copyright (C) Marcin Krzysztof Porwit 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/>. +# + +SAMBA_SRC_DIR=../../source +TDB_SRC_DIR=$(SAMBA_SRC_DIR)/tdb + +CFLAGS = -g -I$(SAMBA_SRC_DIR)/include -I$(TDB_SRC_DIR)/include +CC = gcc + +PROGS = perfcount +TDB_OBJ = $(TDB_SRC_DIR)/common/tdb.o $(TDB_SRC_DIR)/common/dump.o \ + $(TDB_SRC_DIR)/common/error.o $(TDB_SRC_DIR)/common/freelist.o \ + $(TDB_SRC_DIR)/common/io.o $(TDB_SRC_DIR)/common/lock.o \ + $(TDB_SRC_DIR)/common/open.o $(TDB_SRC_DIR)/common/transaction.o \ + $(TDB_SRC_DIR)/common/traverse.o +PERF_WRITER_OBJ = perf_writer.o perf_writer_mem.o perf_writer_util.o perf_writer_cpu.o perf_writer_process.o perf_writer_disk.o + +default: $(PROGS) + +perfcount: $(PERF_WRITER_OBJ) + $(CC) $(CFLAGS) -o perfcount $(PERF_WRITER_OBJ) $(TDB_OBJ) + +clean: + rm -f $(PROGS) *.o *~ *% core diff --git a/examples/perfcounter/perf.h b/examples/perfcounter/perf.h new file mode 100644 index 0000000000..2c24d31260 --- /dev/null +++ b/examples/perfcounter/perf.h @@ -0,0 +1,195 @@ +/* + * Unix SMB/CIFS implementation. + * Performance Counter Daemon + * + * Copyright (C) Marcin Krzysztof Porwit 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/>. + */ + +#ifndef __PERF_H__ +#define __PERF_H__ + +#include <stdlib.h> +#include <time.h> +#include <math.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <signal.h> +#include <stdarg.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/wait.h> +#include <limits.h> +#include "tdb.h" +#include <rpc_perfcount_defs.h> +#include <sys/statfs.h> +#include <sys/times.h> +#include <sys/sysinfo.h> + +#define NUM_COUNTERS 10 + +#define NAME_LEN 256 +#define HELP_LEN 1024 + +#define PERF_OBJECT 0 +#define PERF_INSTANCE 1 +#define PERF_COUNTER 2 + +#define FALSE 0 +#define TRUE !FALSE + +#define PROC_BUF 256 +#define LARGE_BUF 16384 + +typedef struct perf_counter +{ + int index; + char name[NAME_LEN]; + char help[HELP_LEN]; + char relationships[NAME_LEN]; + unsigned int counter_type; + int record_type; +} PerfCounter; + +typedef struct mem_data +{ + unsigned int availPhysKb; + unsigned int availSwapKb; + unsigned int totalPhysKb; + unsigned int totalSwapKb; +} MemData; + +typedef struct mem_info +{ + PerfCounter memObjDesc; + PerfCounter availPhysKb; + PerfCounter availSwapKb; + PerfCounter totalPhysKb; + PerfCounter totalSwapKb; + MemData *data; +} MemInfo; + +typedef struct cpu_data +{ + unsigned long long user; + unsigned long long nice; + unsigned long long system; + unsigned long long idle; +} CPUData; + +typedef struct cpu_info +{ + unsigned int numCPUs; + PerfCounter cpuObjDesc; + PerfCounter userCPU; + PerfCounter niceCPU; + PerfCounter systemCPU; + PerfCounter idleCPU; + CPUData *data; +} CPUInfo; + +typedef struct disk_meta_data +{ + char name[NAME_LEN]; + char mountpoint[NAME_LEN]; +} DiskMetaData; + +typedef struct disk_data +{ + unsigned long long freeMegs; + unsigned int writesPerSec; + unsigned int readsPerSec; +} DiskData; + +typedef struct disk_info +{ + unsigned int numDisks; + DiskMetaData *mdata; + PerfCounter diskObjDesc; + PerfCounter freeMegs; + PerfCounter writesPerSec; + PerfCounter readsPerSec; + DiskData *data; +} DiskInfo; + +typedef struct process_data +{ + unsigned int runningProcessCount; +} ProcessData; + +typedef struct process_info +{ + PerfCounter processObjDesc; + PerfCounter runningProcessCount; + ProcessData *data; +} ProcessInfo; + +typedef struct perf_data_block +{ + unsigned int counter_id; + unsigned int num_counters; + unsigned int NumObjectTypes; + unsigned long long PerfTime; + unsigned long long PerfFreq; + unsigned long long PerfTime100nSec; + MemInfo memInfo; + CPUInfo cpuInfo; + ProcessInfo processInfo; + DiskInfo diskInfo; +} PERF_DATA_BLOCK; + +typedef struct runtime_settings +{ + /* Runtime flags */ + int dflag; + /* DB path names */ + char dbDir[PATH_MAX]; + char nameFile[PATH_MAX]; + char counterFile[PATH_MAX]; + /* TDB context */ + TDB_CONTEXT *cnames; + TDB_CONTEXT *cdata; +} RuntimeSettings; + +/* perf_writer_ng_util.c function prototypes */ +void fatal(char *msg); +void add_key(TDB_CONTEXT *db, char *keystring, char *datastring, int flags); +void add_key_raw(TDB_CONTEXT *db, char *keystring, void *datastring, size_t datasize, int flags); +void make_key(char *buf, int buflen, int key_part1, char *key_part2); +void parse_flags(RuntimeSettings *rt, int argc, char **argv); +void setup_file_paths(RuntimeSettings *rt); +void daemonize(RuntimeSettings *rt); + +/* perf_writer_ng_mem.c function prototypes */ +void get_meminfo(PERF_DATA_BLOCK *data); +void init_memdata_desc(PERF_DATA_BLOCK *data); +void init_memdata(PERF_DATA_BLOCK *data); +void output_mem_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt); +void output_meminfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags); +void init_perf_counter(PerfCounter *counter, PerfCounter *parent, unsigned int index, char *name, char *help, int counter_type, int record_type); + +/* perf_writer_ng_cpu.c function prototypes */ +unsigned long long get_cpufreq(); +void init_cpudata_desc(PERF_DATA_BLOCK *data); +void get_cpuinfo(PERF_DATA_BLOCK *data); +void init_cpu_data(PERF_DATA_BLOCK *data); +void output_cpu_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt); +void output_cpuinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags); + +#endif /* __PERF_H__ */ diff --git a/examples/perfcounter/perf_writer.c b/examples/perfcounter/perf_writer.c new file mode 100644 index 0000000000..4260f9595d --- /dev/null +++ b/examples/perfcounter/perf_writer.c @@ -0,0 +1,213 @@ +/* + * Unix SMB/CIFS implementation. + * Performance Counter Daemon + * + * Copyright (C) Marcin Krzysztof Porwit 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/>. + */ + +#include "perf.h" + +sig_atomic_t keep_running = TRUE; + +/* allocates memory and gets numCPUs, total memory, and PerfFreq, number of disks... */ +void get_constants(PERF_DATA_BLOCK *data) +{ + data->cpuInfo.numCPUs = sysconf(_SC_NPROCESSORS_ONLN) > 0 ? sysconf(_SC_NPROCESSORS_ONLN) : 1; + data->PerfFreq = sysconf(_SC_CLK_TCK); + init_mem_data(data); + init_cpu_data(data); + init_process_data(data); + init_disk_data(data); + + return; +} + +void output_num_instances(PerfCounter obj, int numInst, RuntimeSettings rt) +{ + char key[NAME_LEN]; + char sdata[NAME_LEN]; + + make_key(key, NAME_LEN, obj.index, "inst"); + memset(sdata, 0, NAME_LEN); + sprintf(sdata, "%d", numInst); + add_key(rt.cnames, key, sdata, TDB_INSERT); + + return; +} + +void output_perf_desc(PerfCounter counter, RuntimeSettings rt) +{ + char key[NAME_LEN]; + char sdata[NAME_LEN]; + + /* First insert the counter name */ + make_key(key, NAME_LEN, counter.index, NULL); + add_key(rt.cnames, key, counter.name, TDB_INSERT); + /* Add the help string */ + make_key(key, NAME_LEN, counter.index + 1, NULL); + add_key(rt.cnames, key, counter.help, TDB_INSERT); + /* Add the relationships */ + make_key(key, NAME_LEN, counter.index, "rel"); + add_key(rt.cnames, key, counter.relationships, TDB_INSERT); + /* Add type data if not PERF_OBJECT or PERF_INSTANCE */ + if(counter.record_type == PERF_COUNTER) + { + make_key(key, NAME_LEN, counter.index, "type"); + memset(sdata, 0, NAME_LEN); + sprintf(sdata, "%d", counter.counter_type); + add_key(rt.cnames, key, sdata, TDB_INSERT); + } + + return; +} + +void initialize(PERF_DATA_BLOCK *data, RuntimeSettings *rt, int argc, char **argv) +{ + memset(data, 0, sizeof(*data)); + memset(rt, 0, sizeof(*data)); + + parse_flags(rt, argc, argv); + setup_file_paths(rt); + + get_constants(data); + + if(rt->dflag == TRUE) + daemonize(rt); + + output_mem_desc(data, *rt); + output_cpu_desc(data, *rt); + output_process_desc(data, *rt); + output_disk_desc(data, *rt); + + return; +} + +void refresh_perf_data_block(PERF_DATA_BLOCK *data, RuntimeSettings rt) +{ + data->PerfTime100nSec = 0; + get_meminfo(data); + get_cpuinfo(data); + get_processinfo(data); + get_diskinfo(data); + return; +} + +void output_perf_counter(PerfCounter counter, unsigned long long data, + RuntimeSettings rt, int tdb_flags) +{ + char key[NAME_LEN]; + char sdata[NAME_LEN]; + unsigned int size_mask; + + make_key(key, NAME_LEN, counter.index, NULL); + memset(sdata, 0, NAME_LEN); + + size_mask = counter.counter_type & PERF_SIZE_VARIABLE_LEN; + + if(size_mask == PERF_SIZE_DWORD) + sprintf(sdata, "%d", (unsigned int)data); + else if(size_mask == PERF_SIZE_LARGE) + sprintf(sdata, "%Lu", data); + + add_key(rt.cdata, key, sdata, tdb_flags); + + return; +} + +void output_perf_instance(int parentObjInd, + int instanceInd, + void *instData, + size_t dsize, + char *name, + RuntimeSettings rt, + int tdb_flags) +{ + char key[NAME_LEN]; + char sdata[NAME_LEN]; + + memset(key, 0, NAME_LEN); + sprintf(key, "%di%d", parentObjInd, instanceInd); + add_key_raw(rt.cdata, key, instData, dsize, tdb_flags); + + /* encode name */ + memset(key, 0, NAME_LEN); + sprintf(key, "%di%dname", parentObjInd, instanceInd); + add_key(rt.cnames, key, name, tdb_flags); + + return; +} + +void output_global_data(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags) +{ + int i; + char key[NAME_LEN]; + char sdata[NAME_LEN]; + + /* Initialize BaseIndex */ + make_key(key, NAME_LEN, 1, NULL); + memset(sdata, 0, NAME_LEN); + sprintf(sdata, "%d", data->num_counters); + add_key(rt.cnames, key, sdata, tdb_flags); + /* Initialize PerfTime, PerfFreq and PerfTime100nSec */ + memset(sdata, 0, NAME_LEN); + make_key(key, NAME_LEN, 0, "PerfTime"); + sprintf(sdata, "%Lu", data->PerfTime); + add_key(rt.cdata, key, sdata, tdb_flags); + make_key(key, NAME_LEN, 0, "PerfTime100nSec"); + memset(sdata, 0, NAME_LEN); + sprintf(sdata, "%Lu", data->PerfTime100nSec); + add_key(rt.cdata, key, sdata, tdb_flags); + memset(sdata, 0, NAME_LEN); + make_key(key, NAME_LEN, 0, "PerfFreq"); + sprintf(sdata, "%Lu", data->PerfFreq); + add_key(rt.cnames, key, sdata, tdb_flags); + + return; +} + +void output_perf_data_block(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags) +{ + output_global_data(data, rt, tdb_flags); + output_meminfo(data, rt, tdb_flags); + output_cpuinfo(data, rt, tdb_flags); + output_processinfo(data, rt, tdb_flags); + output_diskinfo(data, rt, tdb_flags); + return; +} + +void update_counters(PERF_DATA_BLOCK *data, RuntimeSettings rt) +{ + refresh_perf_data_block(data, rt); + output_perf_data_block(data, rt, TDB_REPLACE); + + return; +} + +int main(int argc, char **argv) +{ + PERF_DATA_BLOCK data; + RuntimeSettings rt; + + initialize(&data, &rt, argc, argv); + + while(keep_running) + { + update_counters(&data, rt); + sleep(1); + } + + return 0; +} diff --git a/examples/perfcounter/perf_writer_cpu.c b/examples/perfcounter/perf_writer_cpu.c new file mode 100644 index 0000000000..215e073b8d --- /dev/null +++ b/examples/perfcounter/perf_writer_cpu.c @@ -0,0 +1,189 @@ +/* + * Unix SMB/CIFS implementation. + * Performance Counter Daemon + * + * Copyright (C) Marcin Krzysztof Porwit 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/>. + */ + +#include "perf.h" + +void init_cpudata_desc(PERF_DATA_BLOCK *data) +{ + init_perf_counter(&(data->cpuInfo.cpuObjDesc), + &(data->cpuInfo.cpuObjDesc), + get_counter_id(data), + "Processor", + "The Processor object consists of counters that describe the behavior of the CPU.", + 0, + PERF_OBJECT); + init_perf_counter(&(data->cpuInfo.userCPU), + &(data->cpuInfo.cpuObjDesc), + get_counter_id(data), + "\% User CPU Utilization", + "\% User CPU Utilization is the percentage of the CPU used by processes executing user code.", + PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT, + PERF_COUNTER); + init_perf_counter(&(data->cpuInfo.systemCPU), + &(data->cpuInfo.cpuObjDesc), + get_counter_id(data), + "\% System CPU Utilization", + "\% System CPU Utilization is the percentage of the CPU used by processes doing system calls.", + PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT, + PERF_COUNTER); + init_perf_counter(&(data->cpuInfo.niceCPU), + &(data->cpuInfo.cpuObjDesc), + get_counter_id(data), + "\% Nice CPU Utilization", + "\% Nice CPU Utilization is the percentage of the CPU used by processes running in nice mode.", + PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NOSHOW, + PERF_COUNTER); + init_perf_counter(&(data->cpuInfo.idleCPU), + &(data->cpuInfo.cpuObjDesc), + get_counter_id(data), + "\% Idle CPU", + "\% Idle CPU is the percentage of the CPU not doing any work.", + PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NOSHOW, + PERF_COUNTER); + + return; +} + +void get_cpuinfo(PERF_DATA_BLOCK *data) +{ + int num, i; + unsigned int cpuid; + char buf[PROC_BUF]; + static FILE *fp = NULL; + + if(!fp) + { + if(!(fp = fopen("/proc/stat", "r"))) + { + perror("get_cpuinfo: fopen"); + exit(1); + } + } + + rewind(fp); + fflush(fp); + + /* Read in the first line and discard it -- that has the CPU summary */ + if(!fgets(buf, sizeof(buf), fp)) + { + perror("get_cpuinfo: fgets"); + exit(1); + } + for(i = 0; i < data->cpuInfo.numCPUs; i++) + { + if(!fgets(buf, sizeof(buf), fp)) + { + perror("get_cpuinfo: fgets"); + exit(1); + } + num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu", + &cpuid, + &data->cpuInfo.data[i].user, + &data->cpuInfo.data[i].nice, + &data->cpuInfo.data[i].system, + &data->cpuInfo.data[i].idle); + if(i != cpuid) + { + perror("get_cpuinfo: /proc/stat inconsistent?"); + exit(1); + } + /* + Alternate way of doing things: + struct tms buffer; + data->PerfTime100nSec = times(&buffer); + */ + data->PerfTime100nSec += data->cpuInfo.data[i].user + + data->cpuInfo.data[i].nice + + data->cpuInfo.data[i].system + + data->cpuInfo.data[i].idle; + } + data->PerfTime100nSec /= data->cpuInfo.numCPUs; + return; +} + +void init_cpu_data(PERF_DATA_BLOCK *data) +{ + data->cpuInfo.data = calloc(data->cpuInfo.numCPUs, sizeof(*data->cpuInfo.data)); + if(!data->cpuInfo.data) + { + perror("init_cpu_data: out of memory"); + exit(1); + } + + init_cpudata_desc(data); + + get_cpuinfo(data); + + return; +} + +void output_cpu_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt) +{ + output_perf_desc(data->cpuInfo.cpuObjDesc, rt); + output_perf_desc(data->cpuInfo.userCPU, rt); + output_perf_desc(data->cpuInfo.niceCPU, rt); + output_perf_desc(data->cpuInfo.systemCPU, rt); + output_perf_desc(data->cpuInfo.idleCPU, rt); + if(data->cpuInfo.numCPUs > 1) + output_num_instances(data->cpuInfo.cpuObjDesc, data->cpuInfo.numCPUs + 1, rt); + + return; +} + +void output_cpuinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags) +{ + int i; + char buf[NAME_LEN]; + + output_perf_counter(data->cpuInfo.userCPU, + data->cpuInfo.data[0].user, + rt, tdb_flags); + output_perf_counter(data->cpuInfo.systemCPU, + data->cpuInfo.data[0].system, + rt, tdb_flags); + output_perf_counter(data->cpuInfo.niceCPU, + data->cpuInfo.data[0].nice, + rt, tdb_flags); + output_perf_counter(data->cpuInfo.idleCPU, + data->cpuInfo.data[0].idle, + rt, tdb_flags); + if(data->cpuInfo.numCPUs > 1) + { + for(i = 0; i < data->cpuInfo.numCPUs; i++) + { + memset(buf, 0, NAME_LEN); + sprintf(buf, "cpu%d", i); + output_perf_instance(data->cpuInfo.cpuObjDesc.index, + i, + (void *)&(data->cpuInfo.data[i]), + sizeof(data->cpuInfo.data[i]), + buf, rt, tdb_flags); + } + + memset(buf, 0, NAME_LEN); + sprintf(buf, "_Total"); + output_perf_instance(data->cpuInfo.cpuObjDesc.index, + i, + (void *)&(data->cpuInfo.data[i]), + sizeof(data->cpuInfo.data[i]), + buf, rt, tdb_flags); + } + return; +} diff --git a/examples/perfcounter/perf_writer_disk.c b/examples/perfcounter/perf_writer_disk.c new file mode 100644 index 0000000000..15188d2531 --- /dev/null +++ b/examples/perfcounter/perf_writer_disk.c @@ -0,0 +1,224 @@ +/* + * Unix SMB/CIFS implementation. + * Performance Counter Daemon + * + * Copyright (C) Marcin Krzysztof Porwit 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/>. + */ + +#include "perf.h" + +void init_diskdata_desc(PERF_DATA_BLOCK *data) +{ + init_perf_counter(&(data->diskInfo.diskObjDesc), + &(data->diskInfo.diskObjDesc), + get_counter_id(data), + "Logical Disk", + "The Logical Disk object consists of counters that show information about disks.", + 0, + PERF_OBJECT); + init_perf_counter(&(data->diskInfo.freeMegs), + &(data->diskInfo.diskObjDesc), + get_counter_id(data), + "Megabytes Free", + "The amount of available disk space, in megabytes.", + PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX, + PERF_COUNTER); + init_perf_counter(&(data->diskInfo.writesPerSec), + &(data->diskInfo.diskObjDesc), + get_counter_id(data), + "Writes/sec", + "The number of writes per second to that disk.", + PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC, + PERF_COUNTER); + init_perf_counter(&(data->diskInfo.readsPerSec), + &(data->diskInfo.diskObjDesc), + get_counter_id(data), + "Reads/sec", + "The number of reads of that disk per second.", + PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC, + PERF_COUNTER); + + return; +} +void init_num_disks(PERF_DATA_BLOCK *data) +{ + FILE *mtab; + char buf[PROC_BUF]; + char *start, *stop; + int i = 0, num; + + if(!(mtab = fopen("/etc/mtab", "r"))) + { + perror("init_disk_names: fopen"); + exit(1); + } + + rewind(mtab); + fflush(mtab); + + while(fgets(buf, sizeof(buf), mtab)) + { + if(start = strstr(buf, "/dev/")) + { + if(start = strstr(start, "da")) + { + i++; + } + } + } + + data->diskInfo.numDisks = i; + fclose(mtab); + + return; +} + +void init_disk_names(PERF_DATA_BLOCK *data) +{ + FILE *mtab; + char buf[PROC_BUF]; + char *start, *stop; + int i = 0, num; + + if(!(mtab = fopen("/etc/mtab", "r"))) + { + perror("init_disk_names: fopen"); + exit(1); + } + + rewind(mtab); + fflush(mtab); + + while(fgets(buf, sizeof(buf), mtab)) + { + if(start = strstr(buf, "/dev/")) + { + if(start = strstr(start, "da")) + { + start -=1; + stop = strstr(start, " "); + memcpy(data->diskInfo.mdata[i].name, start, stop - start); + start = stop +1; + stop = strstr(start, " "); + memcpy(data->diskInfo.mdata[i].mountpoint, start, stop - start); + i++; + } + } + } + + fclose(mtab); + + return; +} + +void get_diskinfo(PERF_DATA_BLOCK *data) +{ + int i; + DiskData *p; + struct statfs statfsbuf; + int status, num; + char buf[LARGE_BUF], *start; + FILE *diskstats; + long reads, writes, discard; + + diskstats = fopen("/proc/diskstats", "r"); + rewind(diskstats); + fflush(diskstats); + status = fread(buf, sizeof(char), LARGE_BUF, diskstats); + fclose(diskstats); + + for(i = 0; i < data->diskInfo.numDisks; i++) + { + p = &(data->diskInfo.data[i]); + status = statfs(data->diskInfo.mdata[i].mountpoint, &statfsbuf); + p->freeMegs = (statfsbuf.f_bfree*statfsbuf.f_bsize)/1048576; + start = strstr(buf, data->diskInfo.mdata[i].name); + start += strlen(data->diskInfo.mdata[i].name) + 1; + num = sscanf(start, "%u %u %u %u", + &reads, + &discard, + &writes, + &discard); + p->writesPerSec = writes; + p->readsPerSec = reads; + fprintf(stderr, "%s:\t%u\t%u\n", + data->diskInfo.mdata[i].mountpoint, + reads, writes); + } + return; +} +void init_disk_data(PERF_DATA_BLOCK *data) +{ + init_diskdata_desc(data); + + init_num_disks(data); + + data->diskInfo.mdata = calloc(data->diskInfo.numDisks, sizeof(DiskMetaData)); + if(!data->diskInfo.mdata) + { + fatal("init_disk_data: out of memory"); + } + + init_disk_names(data); + + data->diskInfo.data = calloc(data->diskInfo.numDisks, sizeof(DiskData)); + if(!data->diskInfo.data) + { + fatal("init_disk_data: out of memory"); + } + + get_diskinfo(data); + + return; +} + +void output_disk_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt) +{ + output_perf_desc(data->diskInfo.diskObjDesc, rt); + output_perf_desc(data->diskInfo.freeMegs, rt); + output_perf_desc(data->diskInfo.writesPerSec, rt); + output_perf_desc(data->diskInfo.readsPerSec, rt); + output_num_instances(data->diskInfo.diskObjDesc, data->diskInfo.numDisks, rt); + + return; +} + +void output_diskinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags) +{ + int i; + + output_perf_counter(data->diskInfo.freeMegs, + data->diskInfo.data[0].freeMegs, + rt, tdb_flags); + output_perf_counter(data->diskInfo.writesPerSec, + (unsigned long long)data->diskInfo.data[0].writesPerSec, + rt, tdb_flags); + output_perf_counter(data->diskInfo.readsPerSec, + (unsigned long long)data->diskInfo.data[0].readsPerSec, + rt, tdb_flags); + + for(i = 0; i < data->diskInfo.numDisks; i++) + { + output_perf_instance(data->diskInfo.diskObjDesc.index, + i, + (void *)&(data->diskInfo.data[i]), + sizeof(DiskData), + data->diskInfo.mdata[i].mountpoint, + rt, tdb_flags); + } + + return; +} diff --git a/examples/perfcounter/perf_writer_mem.c b/examples/perfcounter/perf_writer_mem.c new file mode 100644 index 0000000000..580207fb64 --- /dev/null +++ b/examples/perfcounter/perf_writer_mem.c @@ -0,0 +1,124 @@ +/* + * Unix SMB/CIFS implementation. + * Performance Counter Daemon + * + * Copyright (C) Marcin Krzysztof Porwit 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/>. + */ + +#include "perf.h" + +void get_meminfo(PERF_DATA_BLOCK *data) +{ + int status; + struct sysinfo info; + status = sysinfo(&info); + + data->memInfo.data->availPhysKb = (info.freeram * info.mem_unit)/1024; + data->memInfo.data->availSwapKb = (info.freeswap * info.mem_unit)/1024; + data->memInfo.data->totalPhysKb = (info.totalram * info.mem_unit)/1024; + data->memInfo.data->totalSwapKb = (info.totalswap * info.mem_unit)/1024; + + /* Also get uptime since we have the structure */ + data->PerfTime = (unsigned long)info.uptime; + + return; +} + +void init_memdata_desc(PERF_DATA_BLOCK *data) +{ + init_perf_counter(&(data->memInfo.memObjDesc), + &(data->memInfo.memObjDesc), + get_counter_id(data), + "Memory", + "The Memory performance object consists of counters that describe the behavior of physical and virtual memory on the computer.", + 0, + PERF_OBJECT); + init_perf_counter(&(data->memInfo.availPhysKb), + &(data->memInfo.memObjDesc), + get_counter_id(data), + "Available Physical Kilobytes", + "Available Physical Kilobytes is the number of free kilobytes in physical memory", + PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX, + PERF_COUNTER); + init_perf_counter(&(data->memInfo.availSwapKb), + &(data->memInfo.memObjDesc), + get_counter_id(data), + "Available Swap Kilobytes", + "Available Swap Kilobytes is the number of free kilobytes in swap space", + PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX, + PERF_COUNTER); + init_perf_counter(&(data->memInfo.totalPhysKb), + &(data->memInfo.memObjDesc), + get_counter_id(data), + "Total Physical Kilobytes", + "Total Physical Kilobytes is a base counter", + PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW, + PERF_COUNTER); + init_perf_counter(&(data->memInfo.totalSwapKb), + &(data->memInfo.memObjDesc), + get_counter_id(data), + "Total Swap Kilobytes", + "Total Swap Kilobytes is a base counter", + PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW, + PERF_COUNTER); + + return; +} + +void init_mem_data(PERF_DATA_BLOCK *data) +{ + data->memInfo.data = calloc(1, sizeof(*data->memInfo.data)); + if(!data->memInfo.data) + { + perror("init_memdata: out of memory"); + exit(1); + } + + init_memdata_desc(data); + + get_meminfo(data); + + return; +} + +void output_mem_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt) +{ + output_perf_desc(data->memInfo.memObjDesc, rt); + output_perf_desc(data->memInfo.availPhysKb, rt); + output_perf_desc(data->memInfo.availSwapKb, rt); + output_perf_desc(data->memInfo.totalPhysKb, rt); + output_perf_desc(data->memInfo.totalSwapKb, rt); + + return; +} + +void output_meminfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags) +{ + output_perf_counter(data->memInfo.availPhysKb, + (unsigned long long)data->memInfo.data->availPhysKb, + rt, tdb_flags); + output_perf_counter(data->memInfo.availSwapKb, + (unsigned long long)data->memInfo.data->availSwapKb, + rt, tdb_flags); + output_perf_counter(data->memInfo.totalPhysKb, + (unsigned long long)data->memInfo.data->totalPhysKb, + rt, tdb_flags); + output_perf_counter(data->memInfo.totalSwapKb, + (unsigned long long)data->memInfo.data->totalSwapKb, + rt, tdb_flags); + + return; +} diff --git a/examples/perfcounter/perf_writer_process.c b/examples/perfcounter/perf_writer_process.c new file mode 100644 index 0000000000..bddceeab15 --- /dev/null +++ b/examples/perfcounter/perf_writer_process.c @@ -0,0 +1,85 @@ +/* + * Unix SMB/CIFS implementation. + * Performance Counter Daemon + * + * Copyright (C) Marcin Krzysztof Porwit 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/>. + */ + +#include "perf.h" + +void get_processinfo(PERF_DATA_BLOCK *data) +{ + int status; + struct sysinfo info; + status = sysinfo(&info); + + data->processInfo.data->runningProcessCount = (unsigned int)info.procs; + + return; +} + +void init_processdata_desc(PERF_DATA_BLOCK *data) +{ + init_perf_counter(&(data->processInfo.processObjDesc), + &(data->processInfo.processObjDesc), + get_counter_id(data), + "Processes", + "%The Processes performance object displays aggregate information about processes on the machine.", + 0, + PERF_OBJECT); + init_perf_counter(&(data->processInfo.runningProcessCount), + &(data->processInfo.processObjDesc), + get_counter_id(data), + "Process Count", + "Process Count is the number of processes currently on the machine.", + PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX, + PERF_COUNTER); + + return; +} + +void init_process_data(PERF_DATA_BLOCK *data) +{ + data->processInfo.data = calloc(1, sizeof(*data->processInfo.data)); + if(!(data->processInfo.data)) + { + perror("init_process_data: out of memory"); + exit(1); + } + + init_processdata_desc(data); + + get_processinfo(data); + + return; +} + +void output_processinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags) +{ + output_perf_counter(data->processInfo.runningProcessCount, + (unsigned long long)data->processInfo.data->runningProcessCount, + rt, tdb_flags); + + return; +} + +void output_process_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt) +{ + output_perf_desc(data->processInfo.processObjDesc, rt); + output_perf_desc(data->processInfo.runningProcessCount, rt); + + return; +} diff --git a/examples/perfcounter/perf_writer_util.c b/examples/perfcounter/perf_writer_util.c new file mode 100644 index 0000000000..6f1eb16d3e --- /dev/null +++ b/examples/perfcounter/perf_writer_util.c @@ -0,0 +1,235 @@ +/* + * Unix SMB/CIFS implementation. + * Performance Counter Daemon + * + * Copyright (C) Marcin Krzysztof Porwit 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/>. + */ + +#include "perf.h" + +extern sig_atomic_t keep_running; + +void fatal(char *msg) +{ + perror(msg); + exit(1); +} + +void add_key_raw(TDB_CONTEXT *db, char *keystring, void *databuf, size_t datasize, int flags) +{ + TDB_DATA key, data; + + key.dptr = keystring; + key.dsize = strlen(keystring); + data.dptr = databuf; + data.dsize = datasize; + + tdb_store(db, key, data, flags); +} + +void add_key(TDB_CONTEXT *db, char *keystring, char *datastring, int flags) +{ + TDB_DATA key, data; + + key.dptr = keystring; + key.dsize = strlen(keystring); + data.dptr = datastring; + data.dsize = strlen(datastring); + + tdb_store(db, key, data, flags); +} + +void make_key(char *buf, int buflen, int key_part1, char *key_part2) +{ + memset(buf, 0, buflen); + if(key_part2 != NULL) + sprintf(buf, "%d%s", key_part1, key_part2); + else + sprintf(buf, "%d", key_part1); + + return; +} + +void usage(char *progname) +{ + fprintf(stderr, "Usage: %s [-d] [-f <file_path>].\n", progname); + fprintf(stderr, "\t-d: run as a daemon.\n"); + fprintf(stderr, "\t-f <file_path>: path where the TDB files reside.\n"); + fprintf(stderr, "\t\tDEFAULT is /var/lib/samba/perfmon\n"); + exit(1); +} + +void parse_flags(RuntimeSettings *rt, int argc, char **argv) +{ + int flag; + + while((flag = getopt(argc, argv, "df:")) != -1) + { + switch(flag) + { + case 'd': + { + rt->dflag = TRUE; + break; + } + case 'f': + { + memcpy(rt->dbDir, optarg, strlen(optarg)); + break; + } + default: + { + usage(argv[0]); + } + } + } + + return; +} + +void setup_file_paths(RuntimeSettings *rt) +{ + int status; + + if(strlen(rt->dbDir) == 0) + { + /* No file path was passed in, use default */ + sprintf(rt->dbDir, "/var/lib/samba/perfmon"); + } + + sprintf(rt->nameFile, "%s/names.tdb", rt->dbDir); + sprintf(rt->counterFile, "%s/data.tdb", rt->dbDir); + + mkdir(rt->dbDir, 0755); + rt->cnames = tdb_open(rt->nameFile, 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644); + rt->cdata = tdb_open(rt->counterFile, 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644); + + if(rt->cnames == NULL || rt->cdata == NULL) + { + perror("setup_file_paths"); + exit(1); + } + + return; +} + +void sigterm_handler() +{ + keep_running = FALSE; + return; +} + +void daemonize(RuntimeSettings *rt) +{ + pid_t pid; + int i; + int fd; + + /* Check if we're already a daemon */ + if(getppid() == 1) + return; + pid = fork(); + if(pid < 0) + /* can't fork */ + exit(1); + else if(pid > 0) + { + /* we're the parent */ + tdb_close(rt->cnames); + tdb_close(rt->cdata); + exit(0); + } + + /* get a new session */ + if(setsid() == -1) + exit(2); + + /* Change CWD */ + chdir("/"); + + /* close file descriptors */ + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + /* And reopen them as safe defaults */ + fd = open("/dev/null", O_RDONLY); + if(fd != 0) + { + dup2(fd, 0); + close(fd); + } + fd = open("/dev/null", O_WRONLY); + if(fd != 1) + { + dup2(fd, 1); + close(fd); + } + fd = open("/dev/null", O_WRONLY); + if(fd != 2) + { + dup2(fd, 2); + close(fd); + } + + /* handle signals */ + signal(SIGINT, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGTERM, sigterm_handler); + + return; +} + +int get_counter_id(PERF_DATA_BLOCK *data) +{ + data->counter_id += 2; + data->num_counters++; + + return data->counter_id; +} + +void init_perf_counter(PerfCounter *counter, + PerfCounter *parent, + unsigned int index, + char *name, + char *help, + int counter_type, + int record_type) +{ + counter->index = index; + memcpy(counter->name, name, strlen(name)); + memcpy(counter->help, help, strlen(help)); + counter->counter_type = counter_type; + counter->record_type = record_type; + + switch(record_type) + { + case PERF_OBJECT: + sprintf(counter->relationships, "p"); + break; + case PERF_COUNTER: + sprintf(counter->relationships, "c[%d]", parent->index); + break; + case PERF_INSTANCE: + sprintf(counter->relationships, "i[%d]", parent->index); + break; + default: + perror("init_perf_counter: unknown record type"); + exit(1); + } + + return; +} diff --git a/examples/perfcounter/perfcountd.init b/examples/perfcounter/perfcountd.init new file mode 100755 index 0000000000..683e91395b --- /dev/null +++ b/examples/perfcounter/perfcountd.init @@ -0,0 +1,65 @@ +#!/bin/sh +# +# Copyright (C) Gerald Carter 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/>. +# +#################################################################### + +## This file should have uid root, gid sys and chmod 744 + +PATH=/bin:/usr/bin:/sbin:/usr/sbin + +killproc() +{ + pid=`ps aux | grep $1 | egrep -v '(grep|perfcountd)' | awk '{print $2}'` + if [ "$pid" != "" ]; then + kill $pid + fi +} + +# Start/stop processes + +case "$1" +in +start) + /opt/samba/bin/perfcount -d -f /var/lib/samba/perfmon 2> /dev/null + if [ $? -ne 0 ]; then + echo "Failed!" + exit 1 + fi + echo "done!" + ;; +stop) + killproc perfcount + ;; + +status) + pid=`ps aux | grep perfcount | egrep -v '(grep|perfcountd)' | awk '{print $2}'` + if [ "$pid" == "" ]; then + echo "Dead!" + exit 2; + fi + echo "OK!" + ;; +restart) + $0 stop && $0 start + ;; + +*) + echo "Usage: $0 { start|stop|restart|status }" + ;; +esac + + diff --git a/examples/printer-accounting/README b/examples/printer-accounting/README new file mode 100644 index 0000000000..b7ab42acb9 --- /dev/null +++ b/examples/printer-accounting/README @@ -0,0 +1,63 @@ +These are just a few examples of what you can do for printer accounting; +they are really just hacks to show a manager how may pages were being +printed out on his new hp5n :) + +acct-all will run acct-sum and read the log files to generate some +stats. + +Here is a sample output of the raw stats : + +1996-06-10.15:02:15 pkelly master.fcp.oypi.com 538 0 +1996-06-10.15:06:40 pkelly master.fcp.oypi.com 537 0 +1996-06-10.15:32:12 ted master.fcp.oypi.com 547 0 +1996-06-11.09:06:15 violet master.fcp.oypi.com 2667 0 +1996-06-11.09:48:02 violet master.fcp.oypi.com 66304 5 +1996-06-11.09:50:04 violet master.fcp.oypi.com 116975 9 +1996-06-11.09:57:20 violet master.fcp.oypi.com 3013 1 +1996-06-11.10:13:17 pkelly master.fcp.oypi.com 3407 1 +1996-06-11.12:37:06 craig master.fcp.oypi.com 13639 2 +1996-06-11.12:42:23 pkelly master.fcp.oypi.com 13639 2 +1996-06-11.12:45:11 marlene master.fcp.oypi.com 515 0 +1996-06-11.14:17:10 lucie master.fcp.oypi.com 1405 1 +1996-06-11.14:36:03 laura master.fcp.oypi.com 45486 5 +1996-06-11.15:08:21 violet master.fcp.oypi.com 1923 1 +1996-06-11.15:09:42 laura master.fcp.oypi.com 4821 1 +1996-06-11.15:12:28 laura master.fcp.oypi.com 46277 5 +1996-06-11.15:19:38 violet master.fcp.oypi.com 3503 1 +1996-06-11.15:21:49 lucie master.fcp.oypi.com 493 0 +1996-06-11.15:43:36 al master.fcp.oypi.com 3067 1 + +And the output after the acct-sum is done on a full set of files +in /var/log/lp/* + +master[1072] /var/log/lp$ /etc/conf/acct-all + +Sun Jul 21 23:03:16 EDT 1996 + +Pages are approximate ... + +User Jobs Pages Size +al 1 1 2 KB +craig 1 2 13 KB +jack 68 235 1995 KB +laura 88 328 3050 KB +lucie 221 379 3529 KB +marlene 12 151 1539 KB +melanie 83 365 3691 KB +michelle 68 219 1987 KB +mike 2 10 81 KB +neil 111 225 2753 KB +operator 44 137 1132 KB +pkelly 368 984 11154 KB +root 8 0 29 KB +ted 158 257 2337 KB +tony 244 368 2455 KB +violet 419 1002 10072 KB + + +Printer Jobs Pages +hp2p 3 4 +hp5 915 2135 +lp 978 2524 + +<pkelly@ets.net> diff --git a/examples/printer-accounting/acct-all b/examples/printer-accounting/acct-all new file mode 100644 index 0000000000..dc8f175b3c --- /dev/null +++ b/examples/printer-accounting/acct-all @@ -0,0 +1,9 @@ +#!/bin/sh + +echo "" +date +echo "" +echo "Pages are approximate ..." +echo "" +/etc/conf/acct-sum /var/log/lp/* +echo "" diff --git a/examples/printer-accounting/acct-sum b/examples/printer-accounting/acct-sum new file mode 100644 index 0000000000..ffbfc8d880 --- /dev/null +++ b/examples/printer-accounting/acct-sum @@ -0,0 +1,29 @@ +#!/usr/bin/perl + +while (<>) { + ($date, $user, $machine, $size, $pages) = split(' '); + + $Printer{$ARGV}++; + $PrinterPages{$ARGV} += $pages; + + $Jobs{$user}++; + $Size{$user}+= $size; + $Pages{$user}+= $pages; +} + +printf "%-15s %5s %8s %8s\n", qw(User Jobs Pages Size); +foreach $user (sort keys %Jobs) { + printf "%-15s %5d %8d %8d \KB\n", + $user, $Jobs{$user}, $Pages{$user}, $Size{$user}/1024; +} + + +print "\n\n"; +printf "%-15s %5s %8s %8s\n", qw(Printer Jobs Pages); +foreach $prn (sort keys %Printer) { + ($name = $prn) =~ s=.*/==; + printf "%-15s %5d %8d\n", + $name, $Printer{$prn}, $PrinterPages{$prn}; +} + + diff --git a/examples/printer-accounting/hp5-redir b/examples/printer-accounting/hp5-redir new file mode 100644 index 0000000000..ea1299068a --- /dev/null +++ b/examples/printer-accounting/hp5-redir @@ -0,0 +1,40 @@ +#!/usr/bin/perl +# +# 0 == stdin == docuement +# 1 == stdout == printer +# 2 == stderr == logging +# +# With redirection to another valid /etc/printcap entry +# + +umask(002); + +# -w132 -l66 -i0 -n pkelly -h master.fcp.oypi.com /var/log/lp-acct +require "getopts.pl"; +&Getopts("w:l:i:n:h:"); + +chomp($date = `date '+%Y-%m-%d.%T'`); + +($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, + $atime,$mtime,$ctime,$blksize,$blocks) + = stat(STDIN); + +# send to the real printer now. +open(P, "|lpr -Pmgmt0") || die "Can't print to hp5-real ($!)\n"; +$cnt = 0; +while (sysread(STDIN, $buf, 10240)) { + print P $buf; + # this is ugly, but it gives the approx in pages. We + # don't print graphics, so ... There must be a better way :) + $cnt += ($buf =~ /^L/g); +} +close(P); + +$acct = shift; +if (open(ACCT, ">>$acct")) { + print ACCT "$date $opt_n $opt_h $size $cnt\n"; + close(ACCT); +} else { + warn "Err: Can't account for it ($!)\n"; + warn "Log: $date $opt_n $opt_h $size $cnt\n"; +} diff --git a/examples/printer-accounting/lp-acct b/examples/printer-accounting/lp-acct new file mode 100644 index 0000000000..91a3def08f --- /dev/null +++ b/examples/printer-accounting/lp-acct @@ -0,0 +1,35 @@ +#!/usr/bin/perl +# +# 0 == stdin == docuement +# 1 == stdout == printer +# 2 == stderr == logging +# +# Regular, with no redirection +# + +umask(002); + +# -w132 -l66 -i0 -n pkelly -h master.fcp.oypi.com /var/log/lp-acct +require "getopts.pl"; +&Getopts("w:l:i:n:h:"); + +chomp($date = `date '+%Y-%m-%d.%T'`); + +($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, + $atime,$mtime,$ctime,$blksize,$blocks) + = stat(STDIN); + +$cnt = 0; +while (sysread(STDIN, $buf, 10240)) { + print $buf; + $cnt += ($buf =~ /^L/g); +} + +$acct = shift; +if (open(ACCT, ">>$acct")) { + print ACCT "$date $opt_n $opt_h $size $cnt\n"; + close(ACCT); +} else { + warn "Err: Can't account for it ($!)\n"; + warn "Log: $date $opt_n $opt_h $size $cnt\n"; +} diff --git a/examples/printer-accounting/printcap b/examples/printer-accounting/printcap new file mode 100644 index 0000000000..976005a097 --- /dev/null +++ b/examples/printer-accounting/printcap @@ -0,0 +1,22 @@ +# HP5N - Accounting entry +# +# This file calls the filter, hp5-redir to do the numbers and then +# is redirected to the real entry, mgmt0, which is a remote HP5N +# on the LAN with it's own IP number. +# +hp5:lp=/dev/lp1:\ + :sd=/usr/spool/lpd/hp5-acct:\ + :lf=/var/log/lp-err:\ + :af=/var/log/lp/hp5:\ + :if=/usr/local/bin/lp/hp5-redir:\ + :sh:sf:\ + :mx#0: + +# HP5N - Real printer location +mgmt0:\ + :rm=hp5.fcp.oypi.com:\ + :rp=hp5.fcp.oypi.com:\ + :sd=/usr/spool/lpd/mgmt0:\ + :sh:sf:\ + :mx#0: + diff --git a/examples/printing/VampireDriversFunctions b/examples/printing/VampireDriversFunctions new file mode 100644 index 0000000000..3d46411e91 --- /dev/null +++ b/examples/printing/VampireDriversFunctions @@ -0,0 +1,1656 @@ +#!/bin/bash + +##################################################################### +## +## smb.conf parser class +## +## Copyright (C) Kurt Pfeifle <kpfeifle@danka.de>, 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/>. +## +###################################################################### + +###################################################################### +## Here an example calling sequence +##!/bin/sh +## set -x +## source VampireDriversFunctions + +## +## Start local variables +## +## You must define these variable (possibly in a source script) + +## nthost=192.168.17.1 +## printeradmin=Administrator +## adminpasswd=not4you + +## smbhost=knoppix +## smbprinteradmin=knoppix +## smbadminpasswd=knoppix +## +## End of local variables +## + +## +## functions to call +## + +## fetchenumdrivers3listfromNThost # repeat, if no success at first +## createdrivernamelist +## createprinterlistwithUNCnames # repeat, if no success at first +## createmapofprinterstodriver +## splitenumdrivers3list +## makesubdirsforWIN40driverlist +## splitWIN40fileintoindividualdriverfiles +## fetchtheWIN40driverfiles +## uploadallWIN40drivers +## makesubdirsforW32X86driverlist +## splitW32X86fileintoindividualdriverfiles +## fetchtheW32X86driverfiles +## uploadallW32X86drivers + +## End of example calling sequence +###################################################################### + + +# ----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- +function vampiredrivers_readme() +{ +echo -e " \n\ +############################################################################ +# +# About the \"Vampire Printer Drivers\" set of functions.... +# -------------------------------------------------------- +# +# (C) Kurt Pfeifle <kpfeifle@danka.de>, 2004 +# License: GPL +# +# ------------------------------------------------------------ +# +# Version: 0.8 (largely \"self-documented\" now, but not yet +# completely -- if it ever will be....) +# +# Thanks a lot to Fabian Franz for helping me with some important +# Bash-Scripting-Questions! +# +# This set of functions provides a framework to snatch all printer +# driver info and related files from a Windows NT print server. +# It then uploads and installs the drivers to a Samba server. (The +# Samba server needs to be prepared for this: a valid [print$] +# share, with write access set for a \"printer admin\".) +# +# The main commands used are \"smbclient\" and \"rpcclient\" combined +# with \"grep\", \"sed\" and \"awk\". Probably a Perl or Python script +# would be better suited to do this, mainly because we have to cope +# with printer and driver names which are containing spaces in +# them, so a lot of shell escaping is required to handle these. +# Also, I am not very savvy in scripting, so I invented some very +# obscure methods to work around my knowledge gaps. When I download +# the driver files from the Windows NT box, I put all related driver +# files into their own sub directory, using the same name as the +# driver. Also, driver versions \"0\", \"2\" and \"3\" are placed in +# further subdirectories. +# +# +# Known problems: +# --------------- +# +# 1) I found one printer driver containing a \"slash\" which is not +# handled by this script: \"HP Color LaserJet 5/5M PS\". (There +# are more of these in the wild, of course.) -- The reason: I +# didn't find a way to create a Unix directory containing a \"slash\". +# UPDATE: The script replaces the \"/\" with a \"_\" and also renames +# the drivername accordingly, when it is uploaded to the Samba +# [print$] share.... +# +# 2) There is an unsolved problem in case a real file name deviates +# in its case sensitive spelling from how it is displayed by the +# \"rpcclient enumdrivers\" command. I encountered cases where +# rpcclient displayed \"PS5UI.DLL\" as a file name, but \"smbclient +# mget\" retrieved \"ps5ui.dll\" from the NT printserver, and the +# driverinstallation failed because \"smbclient mput\" tried to put +# \"PS5UI.DLL\" back onto the Samba server where UNIX only had +# \"ps5ui.dll\" available (which of course failed). -- UPDATE: this +# is now solved. All files are renamed now to the same +# case-sensitive spelling as \"rpcclient ... enumdrivers 3\" +# announces. This includes renaming into both, uppercase or +# lowercase, as the case might be.... +# +# 3) This script is probably not portable at all and relies on lots +# of Bash-isms. +# +# 4) This script runs with rpcclient from Samba-3.0.2a (or later) only +# (because it uses the \"Version\" parameter for \"adddriver\"). +# +# The following functions use a few external variables to log +# into the 2 hosts. We suggest that you create a file which +# contains the variables and that you source that file at the +# beginning of this script... +# +# ################################################################# +# +# ntprinteradmin=Administrator # any account on the NT host +# # with \"printer admin\" privileges +# ntadminpasswd=not4you # the \"printer admin\" password on +# # the NT print server +# nthost=windowsntprintserverbox # the netbios name of the NT print +# # server +# +# smbprinteradmin=knoppix # an account on the Samba server +# # with \"printer admin\" privileges +# smbadminpasswd=2secret4you # the \"printer admin\" password on +# # the Samba server +# smbhost=knoppix # the netbios name of the Samba +# # print server +# +# ################################################################# +# +# +# NOTE: these functions also work for 2 NT print servers: snatch all +# drivers from the first, and upload them to the second server (which +# takes the role of the \"Samba\" server). Of course they also work +# for 2 Samba servers: snatch all drivers from the first (which takes +# the role of the NT print server) and upload them to the second.... +# +# +# ............PRESS \"q\" TO QUIT............" \ +|less +} + + +#set -x + + +# ----------------------------------------------------------------------------- +# ----------- print a little help... ------------------------------------------ +# ----------------------------------------------------------------------------- + +function helpwithvampiredrivers() +{ +if stringinstring help $@ ; then +helpwithvampiredrivers ; +else + echo " "; + echo " 1. Run the functions of this script one by one."; + echo " "; + echo " 2. List all functions with the \"enumallfunctions\" call."; + echo " "; + echo " 3. After each functions' run, check if it completed successfully."; + echo " "; + echo " 4. For each function, you can ask for separate help by typing"; + echo " \"<functionname> --help\"." + echo " "; + echo " 5. Often network conditions prevent the MS-RPC calls" + echo " implemented by Samba to succeed at the first attempt." + echo " You may have more joy if you try more than once or twice...."; + echo " "; + echo " 6. I can not support end-users who have problems with this script." + echo " However, we are available for paid, professional consulting," + echo " training and troubleshooting work."; + echo " "; + echo " "; +fi +} + +# ----------------------------------------------------------------------------- +# ----------- enumerate all builtin functions... ------------------------------ +# ----------------------------------------------------------------------------- +function enumallfunctions() +{ +if stringinstring help $@ ; then +helpwithvampiredrivers ; +else + echo " " + echo " " + echo "--> Running now function enumallfunctions()..." + echo "==============================================" + echo -e " \n\ + + NOTE: run the listed functions in the same order as listed below. + + EXAMPLE: \"knoppix@ttyp6[knoppix]$ helpwithvampiredrivers\" + + HELP: the \"--help\" parameter prints usage hints regarding a function. + + EXAMPLE: \"knoppix@ttyp6[knoppix]$ fetchenumdrivers3listfromNThost --help\" + + + function vampiredrivers_readme() + function enumallfunctions() + function helpwithvampiredrivers() + function fetchenumdrivers3listfromNThost() # repeat, if no success at first + function createdrivernamelist() + function createprinterlistwithUNCnames() # repeat, if no success at first + function createmapofprinterstodrivers() + function splitenumdrivers3list() + function makesubdirsforW32X86driverlist() + function splitW32X86fileintoindividualdriverfiles() + function fetchallW32X86driverfiles() + function uploadallW32X86drivers() + function makesubdirsforWIN40driverlist() + function splitWIN40fileintoindividualdriverfiles() + function fetchallWIN40driverfiles() + function uploadallWIN40drivers()" + echo " " +fi +} + +# this is a helperfunction (Thanks to Fabian Franz!) +function stringinstring() +{ + case "$2" in *$1*) + return 0 + ;; + esac + return 1 +} + +# ----------------------------------------------------------------------------- +# ----------- Create an "enumprinters 3" list --------------------- ----------- +# ----------------------------------------------------------------------------- +# + +function helpwithfetchenumdrivers3listfromNThost() +{ +echo -e " \n\ +################################################################################ +# +# About fetchenumdrivers3listfromNThost().... +# ------------------------------------------- +# +# PRECONDITIONS: 1) This function expects write access to the current directory. +# 2) This function expects to have the '\$nthosts', +# '\$ntprinteradmin' and '\$ntadminpasswd' variables set to +# according values. +# +# WHAT IT DOES: This function connects to the '\$nthost' (using the credentials +# '\$ntprinteradmin' with '\$ntadminpasswd', retrieves a list of +# drivers (with related file names) from that host, and saves the +# list under the name of '\${nthost}/enumdrivers3list.txt' (ie. it +# also creates the '\$nthost' subdirectory in the current one). It +# further prints some more info to stdout. +# +# IF IT DOESN'T WORK: It may happen that the function doesn't work at the first +# time (there may be a connection problem). Just repeat a +# few times. It may work then. You will recognize if it +# does. +# +# HINT: The current values: 'nthost'=\"$nthost\" +# 'ntprinteradmin'=\"$ntprinteradmin\" +# 'ntadminpasswd'=<not shown here, check yourself!> +# +################################################################################" +echo " " +} + +# ----------------------------------------------------------------------------- + +function fetchenumdrivers3listfromNThost() +{ +if stringinstring help $@ ; then +helpwithfetchenumdrivers3listfromNThost; +else + echo " " + echo " " + echo "--> Running now function fetchenumdrivers3listfromNThost" + echo "========================================================" + [ -d ${nthost} ] || mkdir "${nthost}"; + rpcclient -U${ntprinteradmin}%${ntadminpasswd} -c 'enumdrivers 3' ${nthost} \ + | sed -e '/^.*Driver Name: \[.*\]/ y/\//_/' \ + | tee \ + ${nthost}/enumdrivers3list.txt; + + NUMBEROFDIFFERENTDRIVERNAMES=$( grep "Driver Name:" ${nthost}/enumdrivers3list.txt \ + | sort -f \ + | uniq \ + | wc -l ); + + echo " "; + echo "--> Finished in running function fetchenumdrivers3listfromNThost...."; + echo "====================================================================" + echo "NUMBEROFDIFFERENTDRIVERNAMES retrieved from \"${nthost}\" is $NUMBEROFDIFFERENTDRIVERNAMES".; + echo " --> If you got \"0\" you may want to try again. <---"; + echo "================================================================"; + echo " "; + enumdrivers3list=`cat ${nthost}/enumdrivers3list.txt`; +fi +} + + +# ----------------------------------------------------------------------------- +# ----------- Create a list of all available drivers installed ---------------- +# ------------------------on the NT print server------------------------------- +# ----------------------------------------------------------------------------- +# + +function helpwithcreatedrivernamelist() +{ +echo -e " \n\ +################################################################################ +# +# About createdrivernamelist()... +# ------------------------------- +# +# PRECONDITIONS: 1) This function expects to find the subdirectory '\$nthost' +# and the file '\${nthost}/enumdrivers3list.txt' to exist. +# 2) This function expects to have the '\$nthosts' variable set +# to an according value. +# +# WHAT IT DOES: This function dissects the '\${nthost}/enumdrivers3list.txt' +# and creates other textfiles from its contents: +# - '\${nthost}/drvrlst.txt' +# - '\${nthost}/completedriverlist.txt' +# and further prints some more info to stdout. +# +# HINT: The current value: 'nthost'=\"$nthost\" +# +################################################################################" +} + +# ----------------------------------------------------------------------------- + +function createdrivernamelist() +{ +if stringinstring help $@ ; then +helpwithcreatedrivernamelist; +else + echo " "; + echo " "; + echo "--> Running now function createdrivernamelist...."; + echo "================================================="; + cat ${nthost}/enumdrivers3list.txt \ + | grep "Driver Name:" \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | sort -f \ + | uniq \ + | tr / _ \ + | sed -e 's/$/\"/' -e 's/^ */\"/' \ + | tee \ + ${nthost}/drvrlst.txt; + drvrlst=$(echo ${nthost}/drvrlst.txt); + + cat ${nthost}/enumdrivers3list.txt \ + | grep "Driver Name:" \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | sort -f \ + | uniq \ + | sed -e 's/$/\"/' \ + | cat -n \ + | sed -e 's/^ */DRIVERNAME/' -e 's/\t/\="/' \ + | tee \ + ${nthost}/completedriverlist.txt; + + NUMBEROFDRIVERS=`cat ${nthost}/completedriverlist.txt| wc -l`; + echo " "; + echo "--> Finished in running function createdrivernamelist...."; + echo "===============================================================================" + echo "NUMBEROFDRIVERS retrieve-able from \"${nthost}\" is $NUMBEROFDRIVERS".; + echo " --> If you got \"0\" you may want to run \"fetchenumdrivers3listfromNThost\"" + echo " again. <---"; + echo "==============================================================================="; + echo " "; + driverlist=`cat ${nthost}/completedriverlist.txt`; + + # alternative method suggested by Fabian Franz: + # | awk 'BEGIN {n=1} { print "DRIVERNAME"n"=\""$0"\""; n=n+1 } ' +fi +} + + + +# ----------------------------------------------------------------------------- +# ----------- Create a list of all available printers ------------------------- +# ----------------------------------------------------------------------------- +# + +function helpwithcreateprinterlistwithUNCnames() +{ +echo -e " \n\ +################################################################################ +# +# About createprinterlistwithUNCnames()... +# ---------------------------------------- +# +# PRECONDITIONS: 1) This function expects write access to the current directory. +# 2) This function expects to have the '\$nthost', +# '\$ntprinteradmin' and '\$ntadminpasswd' variables set to +# according values. +# +# WHAT IT DOES: This function connects to the '\$nthost' (using the credentials +# '\$ntprinteradmin' with '\$ntadminpasswd'), retrieves a list of +# printqueues (with associated driver names) from that host (with +# the help of the 'rpcclient ... enumprinters' utility, and saves +# it under name and path '\${nthost}/printerlistwithUNCnames.txt' +# (ie. it also creates the '\$nthost' subdirectory in the current +# one). It further prints some more info to stdout. +# +# IF IT DOESN'T WORK: It may happen that the function doesn't work at the first +# time (there may be a connection problem). Just repeat a +# few times. It may work then. You will recognize if it does. +# +# HINT: The current values: 'nthost'=\"$nthost\" +# 'ntprinteradmin'=\"$ntprinteradmin\" +# 'ntadminpasswd'=<not shown here, check yourself!> +# +################################################################################" +} + +# ----------------------------------------------------------------------------- + +function createprinterlistwithUNCnames() +{ +if stringinstring help $@ ; then +helpwithcreateprinterlistwithUNCnames ; +else + [ -d ${nthost} ] || mkdir -p ${nthost}; + echo " " + echo " " + echo " " + echo "--> Running now function createprinterlistwithUNCnames()...." + echo "============================================================" + rpcclient -U"${ntprinteradmin}%${ntadminpasswd}" -c 'enumprinters' ${nthost} \ + | grep "description:" \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | sort -f \ + | uniq \ + | tee \ + ${nthost}/printerlistwithUNCnames.txt; + + NUMBEROFPRINTERS=`cat ${nthost}/printerlistwithUNCnames.txt| wc -l`; + echo " "; + echo "--> Finished in running function createprinterlistwithUNCnames...."; + echo "==========================================================================" + echo "NUMBEROFPRINTERS retrieved from \"${nthost}\" is $NUMBEROFPRINTERS".; + echo " --> If you got \"0\" you may want to try again. <---"; + echo "=========================================================================="; + echo " "; + printerlistwithUNCnames=`cat ${nthost}/printerlistwithUNCnames.txt`; +fi +} + + +# ----------------------------------------------------------------------------- +# ----------- Create a list of all printers which have (no) drivers ----------- +# ----------------------------------------------------------------------------- +# + +function helpwithcreatemapofprinterstodrivers() +{ +echo -e " \n\ +################################################################################ +# +# About createmapofprinterdrivers()... +# ------------------------------------ +# +# PRECONDITIONS: 1) This function expects to find a subdirectory '\$nthost' and +# the file '\${nthost}/printerlistwithUNCnames.txt' to exist. +# 2) This functions expects to have the '\$nthosts' variable set +# to an according value. +# +# WHAT IT DOES: This function dissects '\${nthost}/printerlistwithUNCnames.txt' +# and creates some other textfiles from its contents: +# - '\${nthost}/allprinternames.txt' +# - '\${nthost}/alldrivernames.txt' +# - '\${nthost}/allnonrawprinters.txt' +# - '\${nthost}/allrawprinters.txt' +# - '\${nthost}/printertodrivermap.txt' +# and further prints some more info to stdout. +# +# HINT: You currently have defined: 'nthost'=\"$nthost\", which resolves above +# mentioned paths to: +# - '${nthost}/allprinternames.txt' +# - '${nthost}/alldrivernames.txt' +# - '${nthost}/allnonrawprinters.txt' +# - '${nthost}/allrawprinters.txt' +# - '${nthost}/printertodrivermap.txt' +# +################################################################################" +} + +# ----------------------------------------------------------------------------- + +function createmapofprinterstodrivers() +{ +if stringinstring help $@ ; then +helpwithcreatemapofprinterstodrivers ; +else + echo " " + echo " " + echo "--> Running now function createmapofprinterstodrivers()...." + echo "===========================================================" + echo " " + echo " " + echo "ALL PRINTERNAMES:" + echo "=================" + echo " " + cat ${nthost}/printerlistwithUNCnames.txt \ + | awk -F "\\" '{ print $4 }' \ + | awk -F "," '{print $1}' \ + | sort -f \ + | uniq \ + | tee \ + ${nthost}/allprinternames.txt; + + echo " " + echo " " + echo "ALL non-RAW PRINTERS:" + echo "=====================" + echo " " + cat ${nthost}/printerlistwithUNCnames.txt \ + | grep -v ",," \ + | awk -F "\\" '{ print $4 }' \ + | awk -F "," '{print $1}' \ + | sort -f \ + | uniq \ + | tee \ + ${nthost}/allnonrawprinters.txt; + + echo " " + echo " " + echo "ALL RAW PRINTERS:" + echo "================" + echo " " + cat ${nthost}/printerlistwithUNCnames.txt \ + | grep ",," \ + | awk -F "\\" '{ print $4 }' \ + | awk -F "," '{print $1}' \ + | sort -f \ + | uniq \ + | tee \ + ${nthost}/allrawprinters.txt; + + echo " " + echo " " + echo "THE DRIVERNAMES:" + echo "================" + cat ${nthost}/printerlistwithUNCnames.txt \ + | awk -F "," '{print $2 }' \ + | grep -v "^$" \ + | tee \ + ${nthost}/alldrivernames.txt; + + echo " " + echo " " + echo "THE PRINTER-TO-DRIVER-MAP-FOR-non-RAW-PRINTERS:" + echo "===============================================" + cat ${nthost}/printerlistwithUNCnames.txt \ + | awk -F "\\" '{ print $4 }' \ + | awk -F "," '{ print "\"" $1 "\":\"" $2 "\"" }' \ + | grep -v ":\"\"$" \ + | tee \ + ${nthost}/printertodrivermap.txt + echo -e "##########################\n# printer:driver #" >> ${nthost}/printertodrivermap.txt +fi +} + + +# ----------------------------------------------------------------------------- +# ----------- Create a list of all printers which have drivers ---------------- +# ----------------------------------------------------------------------------- +# + +function helpwithgetdrivernamelist() +{ +echo -e " \n\ +################################################################################ +# +# About getdrivernamelist()... +# ---------------------------- +# +# PRECONDITIONS: 1) This function expects to find the subdirectory '\$nthost\' +# otherwise it creates it... +# +# WHAT IT DOES: This function creates the '\${nthost}/printernamelist.txt' +# and also prints it to <stdout>. To do so, it must contact the +# '\$nthost' via rpcclient (which in turn needs '\$ntprinteradmin' +# '\$ntadminpasswd' to log in....). +# +# HINT: The current values: 'nthost'=\"$nthost\" +# 'ntprinteradmin'=\"$ntprinteradmin\" +# 'ntadminpasswd'=<not shown here, check yourself!> +# which resolves above mentioned path to: +# - '${nthost}/printernamelist.txt' +# +################################################################################" +} + +# ----------------------------------------------------------------------------- + +function getdrivernamelist() +{ +if stringinstring $@ ; then +helpwithgetdrivernamelist ; +else + [ -d ${nthost} ] || mkdir -p ${nthost}; + echo " " + echo " " + echo "--> Running now function getdrivernamelist()...." + echo "================================================" + rpcclient -U${ntprinteradmin}%${ntadminpasswd} -c 'enumprinters' ${nthost} \ + | grep "description:" \ + | grep -v ",," \ + | awk -F "," '{ print $2 }' \ + | sort -f \ + | uniq \ + | tee \ + ${nthost}/drivernamelist.txt +fi +} + + +# ----------------------------------------------------------------------------- +# ----------- Split the driverfile listing between the architectures ---------- +# ----------------------------------------------------------------------------- +# + +function helpwithsplitenumdrivers3list() +{ +echo -e " \n\ +################################################################################ +# +# About splitenumdrivers3list()... +# -------------------------------- +# +# PRECONDITIONS: 1) This function expects write access to the current directory +# and its subdirs '\$nthost/*'. +# 2) This function expects to have the '\$nthost' variable set to +# the according value. +# +# WHAT IT DOES: This function dissects the '\$nthost/enumdrivers3list.txt' +# (using "sed", "cat", "awk" and "grep"). It splits the list up +# into two different files representing a complete list of drivers +# and files for each of the 2 supported architectures. It creates +# '\${nthost}/W32X86/${nthost}-enumdrivers3list-NTx86.txt' +# and '\${nthost}/WIN40/${nthost}-enumdrivers3list-WIN40.txt'. +# +# IF IT DOESN'T WORK: The function "fetchenumdrivers3listfromNThost" may not +# have been run successfully. This is a precondition for +# the current function. +# +# HINT: You currently have defined: 'nthost'=\"$nthost\", which resolves above +# mentioned paths to: +# - '${nthost}/WIN40/${nthost}-enumdrivers3list-NTx86.txt' +# - '${nthost}/W32X86/${nthost}-enumdrivers3list-NTx86.txt' +# +################################################################################" +} + +# ----------------------------------------------------------------------------- + +function splitenumdrivers3list() +{ +if stringinstring help $@ ; then +helpwithsplitenumdrivers3list ; +else + echo " " + echo " " + echo "--> Running now function splitenumdrivers3list()...." + echo "====================================================" + + [ -d ${nthost}/WIN40 ] || mkdir -p ${nthost}/WIN40; + [ -d ${nthost}/W32X86 ] || mkdir -p ${nthost}/W32X86; + + cat ${nthost}/enumdrivers3list.txt \ + | sed -e '/^\[Windows NT x86\]/,$ d' \ + | tee \ + ${nthost}/WIN40/${nthost}-enumdrivers3list-WIN40.txt ; + + cat ${nthost}/WIN40/${nthost}-enumdrivers3list-WIN40.txt \ + | grep Version \ + | sort -f \ + | uniq \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | tee ${nthost}/WIN40/availableversionsWIN40.txt ; + +# cd ${nthost}/WIN40/ ; +# mkdir $( cat availableversionsWIN40.txt ) 2> /dev/null ; +# cd - ; + + cat ${nthost}/enumdrivers3list.txt \ + | sed -e '/^\[Windows NT x86\]/,$! d' \ + | tee \ + ${nthost}/W32X86/${nthost}-enumdrivers3list-NTx86.txt ; + + cat ${nthost}/W32X86/${nthost}-enumdrivers3list-NTx86.txt \ + | grep Version \ + | sort -f \ + | uniq \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | tee ${nthost}/W32X86/availableversionsW32X86.txt ; + +# cd ${nthost}/W32X86/ ; +# mkdir $( cat availableversionsW32X86.txt ) 2> /dev/null ; +# cd - ; +fi +} + + +# ----------------------------------------------------------------------------- +# ---------- Make subdirs in ./${sambahost}/WIN40/ for each driver.... ------- +# ----------------------------------------------------------------------------- +# + +function helpwithmakesubdirsforWIN40driverlist() +{ +echo -e " \n\ +################################################################################ +# +# About makesubdirsforWIN40driverlist() and makesubdirsforWIN40driverlist ()... +# ----------------------------------------------------------------------------- +# +# PRECONDITIONS: 1) These functions expect write access to the current directory +# 2) These functions expect to have the '\$nthost' variable set +# to the according value. +# 3) These functions expect to find the two files +# '\${nthost}/WIN40/\${nthost}-enumdrivers3list-WIN40.txt' and +# '\${nthost}/W32X86/\${nthost}-enumdrivers3list-NTx86.txt' to +# work on. +# +# WHAT IT DOES: These functions dissect the '$nthost/enumdrivers3list.txt' +# (using "sed", "cat", "awk" and "grep"). They split the input +# files up into individual files representing driver(version)s and +# create appropriate subdirectories for each driver and version +# underneath './\$nthost/<architecture>'. They use the drivernames +# (including spaces) for the directory names. ("/" -- slashes -- +# in drivernames are converted to underscores). +# +# IF IT DOESN'T WORK: The function "fetchenumdrivers3listfromNThost" and +# consecutive ones may not have been run successfully. This +# is a precondition for the current function. +# +# HINT: You currently have defined: 'nthost'=\"$nthost\", which resolves above +# mentioned paths to: +# - '\${nthost}/WIN40/\${nthost}-enumdrivers3list-NTx86.txt' +# - '\${nthost}/W32X86/\${nthost}-enumdrivers3list-NTx86.txt' +# +################################################################################ +# ............PRESS \"q\" TO QUIT............" \ +|less +} + +# ----------------------------------------------------------------------------- + +function makesubdirsforWIN40driverlist() +{ +if stringinstring help $@ ; then +helpwithmakesubdirsforWIN40driverlist ; +else + cat ${nthost}/WIN40/${nthost}-enumdrivers3list-WIN40.txt \ + | grep "Driver Name:" \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | sort -f \ + | uniq \ + | tr / _ \ + | sed -e 's/$/\"/' \ + | sed -e 's/^/mkdir -p '"\"${nthost}"'\/WIN40\//' \ + | tee \ + ${nthost}/makesubdirsforWIN40driverlist.txt; + + sh -x ${nthost}/makesubdirsforWIN40driverlist.txt; + +# rm ${nthost}/makesubdirsforWIN40driverlist.txt; +fi +} + + +# ----------------------------------------------------------------------------- +# ---------- Make subdirs in ./${sambahost}/W32X86/ for each driver.... ------- +# ----------------------------------------------------------------------------- +# + +function makesubdirsforW32X86driverlist() +{ +if stringinstring help $@ ; then +helpwithvampiredrivers ; +else + cat ${nthost}/W32X86/${nthost}-enumdrivers3list-NTx86.txt \ + | grep "Driver Name:" \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | sort -f \ + | uniq \ + | tr / _ \ + | sed -e 's/$/\"/' \ + | sed -e 's/^ */mkdir '\""${nthost}"'\/W32X86\//' \ + | tee \ + ${nthost}/makesubdirsforW32X86driverlist.txt; + + sh -x ${nthost}/makesubdirsforW32X86driverlist.txt; + +# rm ${nthost}/makesubdirsforW32X86driverlist.txt; +fi +} + + + + +# ----------------------------------------------------------------------------- +# ----------- Split the WIN40 driverfile listing of each architecture --------- +# ------------------------ into individual drivers ---------------------------- +# ----------------------------------------------------------------------------- +# + +function helpwithmakesubdirsforWIN40driverlist() +{ +echo -e " \n\ +################################################################################ +# +# About splitWIN40fileintoindividualdriverfiles() and +# splitW32X86fileintoindividualdriverfiles()... +# --------------------------------------------------- +# +# PRECONDITIONS: 1) These functions expect write access to the current directory +# and its subdirs '\$nthost/*/'. +# 2) These functions expect to have the '\$nthost' variable set +# to the according value. +# 3) These functions expect to find the two files +# '\${nthost}/WIN40/\${nthost}-enumdrivers3list-WIN40.txt' and +# '\${nthost}/W32X86/\${nthost}-enumdrivers3list-NTx86.txt' to +# work on. +# +# WHAT IT DOES: 1) These functions create a directory for each printer driver. +# The directory name is identical to the driver name. +# 2) For each supported driver version (\"0\", \"2\" and \"3\") it +# creates a subdirectory as required underneath +# './\$nthost/<architecture>'. +# 3) The directories use the drivernames (including spaces) for +# their names. ("/" - slashes - in drivernames are converted to +# underscores). +# 4) In each subdirectory they dissect the original +# '\$nthost/enumdrivers3list.txt' (using "sed", "cat", "awk" +# and "grep") and store that part describing the related driver +# (under the name \"driverfilesversion.txt\". +# 5) For each driver the files \"Drivername\", \"DriverPath\", +# \"Drivername\", \"Configfile\", \"Helpfile\", \"AllFiles\" and +# \"Dependentfilelist\" are stored in the according directory +# which hold contend that is used by other (downstream) +# functions. +# 6) It creates a file named \"AllFilesIAskFor\" which holds the +# case sensitive names of files it wanted to download. It also +# creates a file named \"AllFilesIGot\" which holds the case +# sensitive spelling of the downloaded files. (Due to +# Microsoft's ingenious file naming tradition, you may have +# asked for a \"PS5UI.DLL\" but gotten a \"ps5ui.dll\". +# 7) The 2 files from 6) will be later compared with the help of +# the \"sdiff\" utility to decide how to re-name the files so +# that the subsequent driver upload command's spelling +# convention is met. +# +# IF IT DOESN'T WORK: The function \"fetchenumdrivers3listfromNThost\" and +# consecutive ones may not have been run successfully. This +# is a precondition for the current function. +# +# HINT: You currently have defined: 'nthost'=\"$nthost\". +# +################################################################################ +# ............PRESS \"q\" TO QUIT............" \ +|less +} + +# ----------------------------------------------------------------------------- + +function splitWIN40fileintoindividualdriverfiles() +{ +if stringinstring help $@ ; then +helpwithmakesubdirsforWIN40driverlist ; +else + echo " " + echo " " + echo "--> Running now function splitWIN40fileintoindividualdriverfiles()..." + echo "=====================================================================" + + for i in ${nthost}/WIN40/*/; do + CWD1="$( pwd )" ; + cd "${i}" ; + echo " " + echo " " + echo " ###########################################################################################" + echo " " + echo " Next driver is \"$( basename "$( pwd)" )\"" + echo " " + echo " ###########################################################################################" + +##### echo "yes" | cp -f ../../../${nthost}/WIN40/${nthost}-enumdrivers3list-WIN40.txt . 2> /dev/null ; + ln -s -f ../${nthost}-enumdrivers3list-WIN40.txt ${nthost}-enumdrivers3list-WIN40.lnk ; + + tac ${nthost}-enumdrivers3list-WIN40.lnk \ + | sed -e '/'"$(basename "$(echo "$PWD")")"'/,/Version/ p' -n \ + | grep Version \ + | uniq \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print "mkdir \"" $1 "\"" }' \ + | tee mkversiondir.txt ; + + sh mkversiondir.txt 2> /dev/null ; + + cat ${nthost}-enumdrivers3list-WIN40.lnk \ + | sed -e '/\['"$(basename "$(echo "$PWD")")"'\]/,/Monitor/ w alldriverfiles.txt' -n ; + + for i in */; do + CWD2="$( pwd )" ; + cd "${i}"; + echo "yes" | cp ../alldriverfiles.txt . 2> /dev/null ; + + cat alldriverfiles.txt \ + | egrep '(\\'"$(basename "$( pwd )")"'\\|Driver Name)' \ + | tee driverfilesversion.txt ; + + Drivername=$( grep "Driver Name:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | sort -f \ + | uniq \ + | tee Drivername ) ; + + DriverPath=$( grep "Driver Path:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | awk -F "WIN40" '{ print $2 }' \ + | awk -F "\\" '{ print $3 }' \ + | sort -f \ + | uniq ) ; + echo "${DriverPath}" \ + | tee DriverPath ; + + Datafile=$( grep "Datafile:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | awk -F "WIN40" '{ print $2 }' \ + | awk -F "\\" '{ print $3 }' \ + | sort -f \ + | uniq ) ; + echo "${Datafile}" \ + | tee Datafile ; + + Configfile=$( grep "Configfile:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | awk -F "WIN40" '{ print $2 }' \ + | awk -F "\\" '{ print $3 }' \ + | sort -f \ + | uniq ) ; + echo "${Configfile}" \ + | tee Configfile ; + + Helpfile=$( grep "Helpfile:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | awk -F "WIN40" '{ print $2 }' \ + | awk -F "\\" '{ print $3 }' \ + | sort -f \ + | uniq ) ; + echo "${Helpfile}" \ + | tee Helpfile ; + + Dependentfilelist=$( grep "Dependentfiles:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | awk -F "WIN40" '{ print $2 }' \ + | awk -F "\\" '{ print $3 }' \ + | sort -f \ + | uniq ) ; + + Dependentfiles=$( echo $Dependentfilelist \ + | sed -e 's/ /,/g ' ) ; + + echo "${Dependentfiles}" \ + | tee Dependentfiles + + AllFiles=$( echo ${Dependentfilelist}; echo ${Helpfile}; echo ${Configfile}; echo ${Datafile}; echo ${DriverPath} ); + + echo "${AllFiles}" \ + | sort -f \ + | uniq \ + | tee AllFiles ; + + for i in $( cat AllFiles ); do echo ${i}; done \ + | sort -f \ + | uniq \ + | tee AllFilesIAskFor ; + + cd "${CWD2}" 1> /dev/null ; + done + +# rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" \ +# -c "adddriver \"${Architecture}\" \"${DriverName}:${DriverPath}:${Datafile}:${Configfile}:${Helpfile}:NULL:RAW:${Dependentfiles}\" ${Version}" \ ${smbhost} + +# rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" \ +# -c "setdriver \"${printername}\" \"${DriverName}\"" \ +# ${smbhost} +# +# rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" \ +# -c "setprinter \"${printername}\" \"Driver was installed and set via MS-RPC (utilized by Kurt Pfeifle\'s set of \"Vampire Printerdrivers\" scripts from Linux)\"" \ +# ${smbhost} + + cd "${CWD1}" 1> /dev/null ; + done; +fi +} + + + + +# ----------------------------------------------------------------------------- +# ---------- Split the W32X86 driverfile listing of each architecture --------- +# ------------------------ into individual drivers ---------------------------- +# ----------------------------------------------------------------------------- +# + +function splitW32X86fileintoindividualdriverfiles() +{ +if stringinstring help $@ ; then +helpwithmakesubdirsforWIN40driverlist ; +else + echo " " + echo " " + echo "--> Running now function splitW32X86fileintoindividualdriverfiles()..." + echo "======================================================================" + + for i in ${nthost}/W32X86/*/; do + CWD1="$( pwd )" ; + cd "${i}" ; + echo " " + echo " " + echo " ###########################################################################################" + echo " " + echo " Next driver is \"$( basename "$( pwd)" )\"" + echo " " + echo " ###########################################################################################" + +###### echo "yes" | cp -f ../../../${nthost}/W32X86/${nthost}-enumdrivers3list-NTx86.txt . 2> /dev/null ; + ln -s -f ../${nthost}-enumdrivers3list-NTx86.txt ${nthost}-enumdrivers3list-NTx86.lnk ; + + tac ${nthost}-enumdrivers3list-NTx86.lnk \ + | sed -e '/'"$(basename "$(echo "$PWD")")"'/,/Version/ p' -n \ + | grep Version \ + | uniq \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print "mkdir \"" $1 "\"" }' \ + | tee mkversiondir.txt ; + + sh mkversiondir.txt 2> /dev/null ; + + cat ${nthost}-enumdrivers3list-NTx86.lnk \ + | sed -e '/\['"$(basename "$(echo "$PWD")")"'\]/,/Monitor/ w alldriverfiles.txt' -n ; + + for i in */; do + CWD2="$( pwd )" ; + cd "${i}"; + echo "yes" | cp ../alldriverfiles.txt . 2> /dev/null ; + + cat alldriverfiles.txt \ + | egrep '(\\'"$(basename "$( pwd )")"'\\|Driver Name)' \ + | tee driverfilesversion.txt ; + + Drivername=$( grep "Driver Name:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | sort -f \ + | uniq \ + | tee Drivername ) ; +# echo "${Drivername}" \ +# | tee Drivername ; + + + DriverPath=$( grep "Driver Path:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | awk -F "W32X86" '{ print $2 }' \ + | awk -F "\\" '{ print $3 }' \ + | sort -f \ + | uniq ) ; + echo "${DriverPath}" \ + | tee DriverPath ; + + Datafile=$( grep "Datafile:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | awk -F "W32X86" '{ print $2 }' \ + | awk -F "\\" '{ print $3 }' \ + | sort -f \ + | uniq ) ; + echo "${Datafile}" \ + | tee Datafile ; + + Configfile=$( grep "Configfile:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | awk -F "W32X86" '{ print $2 }' \ + | awk -F "\\" '{ print $3 }' \ + | sort -f \ + | uniq ) ; + echo "${Configfile}" \ + | tee Configfile ; + + Helpfile=$( grep "Helpfile:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | awk -F "W32X86" '{ print $2 }' \ + | awk -F "\\" '{ print $3 }' \ + | sort -f \ + | uniq ) ; + echo "${Helpfile}" \ + | tee Helpfile ; + + Dependentfilelist=$( grep "Dependentfiles:" driverfilesversion.txt \ + | awk -F "[" '{ print $2 }' \ + | awk -F "]" '{ print $1 }' \ + | awk -F "W32X86" '{ print $2 }' \ + | awk -F "\\" '{ print $3 }' \ + | sort -f \ + | uniq ) ; + + Dependentfiles=$( echo $Dependentfilelist \ + | sed -e 's/ /,/g ' ) ; + + echo "${Dependentfiles}" \ + | tee Dependentfiles + + AllFiles=$( echo ${Dependentfilelist}; echo ${Helpfile}; echo ${Configfile}; echo ${Datafile}; echo ${DriverPath} ) ; + + echo "${AllFiles}" \ + | sort -f \ + | uniq \ + | tee AllFiles ; + + for i in $( cat AllFiles ); do echo ${i}; done \ + | sort -f \ + | uniq \ + | tee AllFilesIAskFor ; + + cd "${CWD2}" 1> /dev/null ; + done + +# rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" \ +# -c "adddriver \"${Architecture}\" \"${DriverName}:${DriverPath}:${Datafile}:${Configfile}:${Helpfile}:NULL:RAW:${Dependentfiles}\" ${Version}" \ ${smbhost} + +# rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" \ +# -c "setdriver \"${printername}\" \"${DriverName}\"" \ +# ${smbhost} +# +# rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" \ +# -c "setprinter \"${printername}\" \"Driver was installed and set via MS-RPC (utilized by Kurt Pfeifle\'s set of \"Vampire Printerdrivers\" scripts from Linux)\"" \ +# ${smbhost} + + cd "${CWD1}" 1> /dev/null ; + done; +fi +} + + + +# ----------------------------------------------------------------------------- +# ------------------ First download the driverfiles........... ---------------- +# ----------------------------------------------------------------------------- +# + +function helpwithfetchallW32X86driverfiles() +{ +echo -e " \n\ +################################################################################ +# +# About fetchallW32X86driverfiles()... +# ------------------------------------ +# +# PRECONDITIONS: 1) This function expects to have the \'\$nthost\' variable set +# to the according value. +# 2) This function expects to find files \"AllFiles\", +# \"AllFilesIAskFor\", and \"AllFilesIGot\" in the directories +# \'\${nthost}/<architecture>/<drivername>/<version>/\'. +# +# WHAT IT DOES: These functions use \"smbclient\" to connect to the NT print +# server \"\$nthost\" and download the printer driver files from +# there. To achieve that in an orderly fashion, the previously +# created subdirectories (named like the drivers to fetch) are +# visited in turn and the related files are downloaded for each +# driver/directory. +# +# IF IT DOESN'T WORK: The function \"fetchenumdrivers3listfromNThost\" and +# consecutive ones may not have been run successfully. This +# is a precondition for the current function. +# +# HINT: The current values: 'nthost'=\"$nthost\" +# 'ntprinteradmin'=\"$ntprinteradmin\" +# 'ntadminpasswd'=<not shown here, check yourself!> +# +################################################################################" +} + +# ----------------------------------------------------------------------------- + +function fetchallW32X86driverfiles() +{ +if stringinstring help $@ ; then +helpwithfetchallW32X86driverfiles ; +else + echo " " + echo " " + echo "--> Running now function fetchallW32X86driverfiles()...." + echo "========================================================" + + CURRENTWD=${PWD} ; + for i in ${nthost}/W32X86/*/*/ ; do \ + cd "${i}"; + + driverversion="$(basename "$(echo "$PWD")")" ; + echo "$(basename "$(echo "$PWD")")" > driverversion ; + + AllFiles=$( cat AllFiles ) ; + + [ -d TheFiles ] || mkdir TheFiles; + + cd TheFiles; + + echo " " + echo "====================================================" + echo "Downloading files now to ${PWD}...."; + echo "====================================================" + echo " " + + # Fetch the Driver files from the Windoze box (printserver) + smbclient -U"${ntprinteradmin}%${ntadminpasswd}" -d 2 \ + //${nthost}/print\$ -c \ + "cd W32X86\\${driverversion};prompt;mget ${AllFiles}" + + ls -1 \ + | sort -f \ + | uniq \ + | tee ../AllFilesIGot ; + + cd ${CURRENTWD} ; + + done ; +fi +} + + +# ----------------------------------------------------------------------------- +# -------------- Now upload the driverfiles and activate them! ---------------- +# Upload files into root "Architecture" directory of Samba'a [print$] share... +# ----------------------------------------------------------------------------- +# + +function helpwithuploadallW32X86drivers() +{ +echo -e " \n\ +################################################################################ +# +# About uploadallW32X86drivers()... +# --------------------------------- +# +# PRECONDITIONS: 1) This function expects to have the '\$nthost', +# '\$ntprinteradmin' and '\$ntadminpasswd' variables set to +# according values. +# 2) This function expects to find the files \"AllFiles\", +# \"AllFilesIGot\" and \"AllFilesIAskFor\" in the +# \"\${nthost}/W32X86<drivername>/<driverversion>/TheFiles\" +# subdirectory. +# +# WHAT IT DOES: This function uses "smbclient" to connect to the new Samba print +# server "\$nthost" and upload the printer driver files into the +# \"[print\$]\" share there. To achieve that in orderly fashion, +# the previously created subdirectories (named like the drivers +# fetched previously from \$smbhost) are visited in turn and the +# related files are uploaded for each driver/directory. For this +# to really succeed, the files \"AllFilesIGot\" and \"AllFilesIAskFor\" +# are compared with the help of the \"sdiff\" utility to decide +# how to re-name the mis-matching filenams, so that the used +# driver upload command's spelling convention is met.... +# +# IF IT DOESN'T WORK: The function "fetchenumdrivers3listfromNThost" and +# consecutive ones may not have been run successfully. This +# is a precondition for the current function. +# +# HINT: The current values: 'nthost'=\"$nthost\" +# 'ntprinteradmin'=\"$ntprinteradmin\" +# 'ntadminpasswd'=<not shown here, check yourself!> +# +################################################################################ +# ............PRESS \"q\" TO QUIT............" \ +|less +} + +# ----------------------------------------------------------------------------- + +function uploadallW32X86drivers() +{ +if stringinstring help $@ ; then +helpwithuploadallW32X86drivers ; +else + echo " " + echo " " + echo "--> Running now function uploadallW32X86drivers()...." + echo "=====================================================" + + for i in ${nthost}/W32X86/*/*/; do \ + CURRENTWD=${PWD} ; + cd "${i}" ; + # we are now in [..]/W32X86/[drvrname]/[2|3]/ + + driverversion="$(basename "$(echo "$PWD")")" ; + + echo "$(basename "$(echo "$PWD")")" > driverversion ; + + cd TheFiles ; + # we are now in [..]/W32X86/[drvrname]/[2|3]/TheFiles + echo " " + echo "====================================================" + echo "Uploading driverfiles now from ${PWD}...."; + echo "====================================================" + echo " " + set -x ; + + smbclient -U"${smbprinteradmin}%${smbadminpasswd}" -d 2 \ + //${smbhost}/print\$ \ + -c "mkdir W32X86;cd W32X86;prompt;mput $( cat ../AllFilesIGot )"; + + cd .. ; + # we are now in [..]/W32X86/[drvrname]/[2|3]/ + +# Now tell Samba that those files are *printerdriver* files.... +# The "adddriver" command will move them to the "0" subdir and create or +# update the associated *.tdb files (faking the MS Windows Registry on Samba) + Drivername="$( cat Drivername )" + + set -x ; + [ x"$( cat Dependentfiles)" == x"" ] && echo NULL > Dependentfiles; + + sdiff -s AllFilesIGot AllFilesIAskFor \ + | tee sdiff-of-Requested-and-Received.txt ; + + [ -s sdiff-of-Requested-and-Received.txt ] \ + || rm -f sdiff-of-Requested-and-Received.txt \ + && cat sdiff-of-Requested-and-Received.txt > ../sdiff-of-Requested-and-Received.txt ; + + cat sdiff-of-Requested-and-Received.txt \ + | sed -e 's/^/mv /' \ + | sed -e 's/ *|/ /' \ + | tee rename-Received-to-Requested-case.txt ; + + sh -x rename-Received-to-Requested-case.txt ; + + mv rename-Received-to-Requested-case.txt rename-Received-to-Requested-case.done ; + + echo " ################ B E G I N DEBUGGING STATEMENT ############" + echo "rpcclient -U\"${smbprinteradmin}%${smbadminpasswd}\" -d 2 \ + -c \'adddriver \"Windows NT x86\" \"$( cat Drivername ):$( cat DriverPath ):$( cat Datafile ):$( cat Configfile ):$( cat Helpfile ):NULL:RAW:$( cat Dependentfiles )\" $( cat driverversion )" \ + ${smbhost} \' ; + echo " ################ E N D DEBUGGING STATEMENT ################" + + rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" -d 2 \ + -c "adddriver \"Windows NT x86\" \"$( cat Drivername ):$( cat DriverPath ):$( cat Datafile ):$( cat Configfile ):$( cat Helpfile ):NULL:RAW:$( cat Dependentfiles )\" $( cat driverversion )" \ + ${smbhost} ; + + set +x ; + + cd ${CURRENTWD} ; + # we are now back to where we started + done; + set +x ; +fi +} + +# Now tell Samba which printqueue this driver is associated with.... +# The "setdriver" command will do just that and create or +# update the associated *.tdb files (faking the MS Windows Registry on Samba) +# rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" \ +# -c "setdriver \"${printername}\" \"${DriverName}\"" \ +# ${smbhost} +# -- NOT YET IMPLEMENTED IN THIS SCRIPT --- +# + +# Now set a nice printer comment and let the world know what we've done +# (or not.... ;-) +# rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" \ +# -c "setprinter \"${printername}\" \"Driver was installed and set via MS-RPC (rpcclient commandline from Linux)\"" \ +# ${smbhost} +# -- NOT YET IMPLEMENTED IN THIS SCRIPT --- +# + + +# ----------------------------------------------------------------------------- +# ------------------ First download the driverfiles........... ---------------- +# ----------------------------------------------------------------------------- +# + +function helpwithfetchallWIN40driverfiles() +{ +echo -e " \n\ +################################################################################ +# +# About fetchallWIN40driverfiles()... +# ----------------------------------- +# +# PRECONDITIONS: 1) This function expects to have the \$nthost variable set to +# the according value. +# 2) This function expects to find the \"AllFiles\" file in +# \"\${nthost}/WIN40<drivername>/<driverversion>/TheFiles\". +# +# WHAT IT DOES: These functions use "smbclient" to connect to the NT print server +# "\$nthost" and download the printer driver files from there. To +# achieve that in an orderly fashion, the previously created +# subdirectories (named like the drivers to fetch) are visited in +# turn and the related files are downloaded for each +# driver/directory. +# +# IF IT DOESN'T WORK: The function "fetchenumdrivers3listfromNThost" and +# consecutive ones may not have been run successfully. This +# is a precondition for the current function. +# +# HINT: The current values: 'nthost'=\"$nthost\" +# 'ntprinteradmin'=\"$ntprinteradmin\" +# 'ntadminpasswd'=<not shown here, check yourself!> +# +################################################################################ +# ............PRESS \"q\" TO QUIT............" \ +|less +} + +# ----------------------------------------------------------------------------- + +function fetchallWIN40driverfiles() +{ +if stringinstring help $@ ; then +helpwithfetchallWIN40driverfiles ; +else + echo " " + echo " " + echo "--> Running now function fetchallWIN40driverfiles()...." + echo "=======================================================" + + CURRENTWD=${PWD} ; + + for i in ${nthost}/WIN40/*/*/; do \ + cd "${i}"; + + driverversion="$(basename "$(echo "$PWD")")" ; + echo "$(basename "$(echo "$PWD")")" > driverversion ; + + AllFiles=$( cat AllFiles ) ; + + [ -d TheFiles ] || mkdir TheFiles; + + cd TheFiles; + + echo " " + echo "====================================================" + echo "Downloading files now to ${PWD}...."; + echo "====================================================" + echo " " + + # Fetch the Driver files from the Windoze box (printserver) + smbclient -U"${ntprinteradmin}%${ntadminpasswd}" -d 2 \ + //${nthost}/print\$ -c \ + "cd WIN40\\${driverversion};prompt;mget ${AllFiles}" ; + + ls -1 \ + | sort -f \ + | uniq \ + | tee ../AllFilesIGot ; + + cd ${CURRENTWD} ; + + done ; +fi +} + + +# ----------------------------------------------------------------------------- +# -------------- Now upload the driverfiles and activate them! ---------------- +# Upload files into root "Architecture" directory of Samba'a [print$] share... +# ----------------------------------------------------------------------------- +# + +function helpwithuploadallWIN40drivers() +{ +echo -e " \n\ +################################################################################ +# +# About uploadallWIN40drivers()... +# -------------------------------- +# +# PRECONDITIONS: 1) This function expects to have '\$smbhost', '\$smbprinteradmin' +# and '\$smbadminpasswd' variables set to according values. +# 2) This function expects to find \"AllFiles\", \"AllFilesIGot\" +# and \"AllFilesIAskFor\" in the subdirectory +# \"\${nthost}/WINI40/<drivername>/<driverversion>/TheFiles\". +# +# WHAT IT DOES: These function uses \"smbclient\" to connect to the new Samba +# print server "\$nthost" and upload the printer driver files into +# the \"[print\$]\" share there. +# To achieve that in an orderly fashion, the previously created +# subdirectories (named like the drivers fetched previously from +# \$smbhost) are visited in turn and the related files are +# uploaded for each driver/directory. +# For this to really succeed, \"AllFilesIGot\" and \"AllFilesIAskFor\" +# are compared with the help of the \"sdiff\" utility to decide +# how to re-name the mis-matching filenams, so that the used +# driver upload command's spelling convention is met.... +# +# IF IT DOESN'T WORK: The function \"fetchenumdrivers3listfromNThost\" and +# consecutive ones may not have been run successfully. This +# is a precondition for the current function. +# +# HINT: The current values: 'nthost'=\"$nthost\" +# 'ntprinteradmin'=\"$ntprinteradmin\" +# 'ntadminpasswd'=<not shown here, check yourself!> +# +################################################################################ +# ............PRESS \"q\" TO QUIT............" \ +|less +} +function uploadallWIN40drivers() +{ +if stringinstring help $@ ; then +helpwithuploadallWIN40drivers ; +else + echo " " + echo " " + echo "--> Running now function uploadallWIN40drivers()...." + echo "====================================================" + + for i in ${nthost}/WIN40/*/*/; do \ + CURRENTWD=${PWD} ; + cd "${i}" ; + # we are now in [..]/WIN40/[drvrname]/[0]/ + + driverversion="$(basename "$(echo "$PWD")")" ; + + echo "$(basename "$(echo "$PWD")")" > driverversion ; + + cd TheFiles ; + # we are now in [..]/WIN40/[drvrname]/[0]/TheFiles + echo " " + echo "====================================================" + echo "Uploading driverfiles now from ${PWD}...."; + echo "====================================================" + echo " " + set -x ; + + smbclient -U"${smbprinteradmin}%${smbadminpasswd}" -d 2 \ + //${smbhost}/print\$ \ + -c "mkdir WIN40;cd WIN40;prompt;mput $( cat ../AllFilesIGot )"; + + cd .. ; + # we are now in [..]/WIN40/[drvrname]/[0]/ + +# Now tell Samba that those files are *printerdriver* files.... +# The "adddriver" command will move them to the "0" subdir and create or +# update the associated *.tdb files (faking the MS Windows Registry on Samba) + Drivername="$( cat Drivername )" + + set -x ; + [ x"$( cat Dependentfiles)" == x"" ] && echo NULL > Dependentfiles; + + sdiff -s AllFilesIGot AllFilesIAskFor \ + | tee sdiff-of-Requested-and-Received.txt ; + + [ -s sdiff-of-Requested-and-Received.txt ] \ + || rm -f sdiff-of-Requested-and-Received.txt \ + && cat sdiff-of-Requested-and-Received.txt > ../sdiff-of-Requested-and-Received.txt ; + + cat sdiff-of-Requested-and-Received.txt \ + | sed -e 's/^/mv /' \ + | sed -e 's/ *|/ /' \ + | tee rename-Received-to-Requested-case.txt ; + + sh -x rename-Received-to-Requested-case.txt ; + + mv rename-Received-to-Requested-case.txt rename-Received-to-Requested-case.done ; + + echo " ################ DEBUGGING STATEMENT " + echo "rpcclient -U\"${smbprinteradmin}%${smbadminpasswd}\" -d 2 \ + -c \'adddriver \"Windows NT x86\" \"$( cat Drivername ):$( cat DriverPath ):$( cat Datafile ):$( cat Configfile ):$( cat Helpfile ):NULL:RAW:$( cat Dependentfiles )\" $( cat driverversion )" \ + ${smbhost}\' ; + echo " ################ DEBUGGING STATEMENT " + + rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" -d 2 \ + -c "adddriver \"Windows 4.0\" \"$( cat Drivername ):$( cat DriverPath ):$( cat Datafile ):$( cat Configfile ):$( cat Helpfile ):NULL:RAW:$( cat Dependentfiles )\" $( cat driverversion )" \ + ${smbhost} ; + + set +x ; + cd ${CURRENTWD} ; + # we are now back to where we started + done; +fi +} + +# Now tell Samba which printqueue this driver is associated with.... +# The "setdriver" command will do just that and create or +# update the associated *.tdb files (faking the MS Windows Registry on Samba) +# rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" \ +# -c "setdriver \"${printername}\" \"${DriverName}\"" \ +# ${smbhost} +# -- NOT YET IMPLEMENTED IN THIS SCRIPT --- +# +# Now set a nice printer comment and let the world know what we've done +# (or not.... ;-) +# rpcclient -U"${smbprinteradmin}%${smbadminpasswd}" \ +# -c "setprinter \"${printername}\" \"Driver was installed and set via MS-RPC (rpcclient commandline from Linux)\"" \ +# ${smbhost} +# -- NOT YET IMPLEMENTED IN THIS SCRIPT --- +# + + +#source ${0} ; + +enumallfunctions; diff --git a/examples/printing/prtpub.c b/examples/printing/prtpub.c new file mode 100644 index 0000000000..2839940b97 --- /dev/null +++ b/examples/printing/prtpub.c @@ -0,0 +1,237 @@ +/* + * Set printer capabilities in DsDriver Keys on remote printer + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002. + * + * 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/>. + */ + +/* This needs to be defined for certain compilers */ +#define WINVER 0x0500 + +#include <tchar.h> +#include <windows.h> +#include <stdio.h> + +#define SAMBA_PORT _T("Samba") + +TCHAR *PrintLastError(void) +{ + static TCHAR msgtxt[1024*sizeof(TCHAR)]; + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, + NULL, GetLastError(), + 0, msgtxt, 0, NULL); + + return msgtxt; +} + +void map_orientation(HANDLE ph, TCHAR *printer, TCHAR *port) +{ + DWORD rot; + TCHAR portrait_only[] = _T("PORTRAIT\0"); + TCHAR both[] = _T("LANDSCAPE\0PORTRAIT\0"); + + /* orentation of 90 or 270 indicates landscape supported, 0 means it isn't */ + rot = DeviceCapabilities(printer, port, DC_BINNAMES, NULL, NULL); + + printf("printOrientationsSupported:\n"); + + if (rot) { + printf("\tPORTRAIT\n\tLANDSCAPE\n"); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printOrientationsSupported"), REG_MULTI_SZ, + both, sizeof(both)); + } else { + printf("\tPORTRAIT\n"); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printOrientationsSupported"), REG_MULTI_SZ, + portrait_only, sizeof(portrait_only)); + } +} + +void map_resolution(HANDLE ph, TCHAR *printer, TCHAR *port) +{ + DWORD num, *res, maxres = 0, i; + + num = DeviceCapabilities(printer, port, DC_ENUMRESOLUTIONS, NULL, NULL); + if ((DWORD) -1 == num) + return; + res = malloc(num*2*sizeof(DWORD)); + num = DeviceCapabilities(printer, port, DC_ENUMRESOLUTIONS, (BYTE *) res, NULL); + for (i=0; i < num*2; i++) { + maxres = (res[i] > maxres) ? res[i] : maxres; + } + printf("printMaxResolutionSupported: %d\n", maxres); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printMaxResolutionSupported"), REG_DWORD, + (BYTE *) &maxres, sizeof(maxres)); +} + +void map_extents(HANDLE ph, TCHAR *printer, TCHAR *port) +{ + DWORD extentval, xval, yval; + + extentval = DeviceCapabilities(printer, port, DC_MINEXTENT, NULL, NULL); + xval = (DWORD) (LOWORD(extentval)); + yval = (DWORD) (HIWORD(extentval)); + printf("printMinXExtent: %d\n", xval); + printf("printMinYExtent: %d\n", yval); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printMinXExtent"), REG_DWORD, (BYTE *) &xval, sizeof(xval)); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printMinYExtent"), REG_DWORD, (BYTE *) &yval, sizeof(yval)); + extentval = DeviceCapabilities(printer, port, DC_MAXEXTENT, NULL, NULL); + xval = (DWORD) (LOWORD(extentval)); + yval = (DWORD) (HIWORD(extentval)); + printf("printMaxXExtent: %d\n", xval); + printf("printMaxYExtent: %d\n", yval); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printMaxXExtent"), REG_DWORD, (BYTE *) &xval, sizeof(xval)); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printMaxYExtent"), REG_DWORD, (BYTE *) &yval, sizeof(yval)); +} + +void map_printrateunit(HANDLE ph, TCHAR *printer, TCHAR *port) +{ + DWORD unit; + TCHAR ppm[] = _T("PagesPerMinute"); + TCHAR ipm[] = _T("InchesPerMinute"); + TCHAR lpm[] = _T("LinesPerMinute"); + TCHAR cps[] = _T("CharactersPerSecond"); + + unit = DeviceCapabilities(printer, port, DC_PRINTRATEUNIT, NULL, NULL); + switch(unit) { + case PRINTRATEUNIT_PPM: + printf("printRateUnit: %s\n", ppm); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printRateUnit"), REG_SZ, ppm, sizeof(ppm)); + break; + case PRINTRATEUNIT_IPM: + printf("printRateUnit: %s\n", ipm); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printRateUnit"), REG_SZ, ipm, sizeof(ipm)); + break; + case PRINTRATEUNIT_LPM: + printf("printRateUnit: %s\n", lpm); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printRateUnit"), REG_SZ, lpm, sizeof(lpm)); + break; + case PRINTRATEUNIT_CPS: + printf("printRateUnit: %s\n", cps); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, _T("printRateUnit"), REG_SZ, cps, sizeof(cps)); + break; + default: + printf("printRateUnit: unknown value %d\n", unit); + } +} + +void map_generic_boolean(HANDLE ph, TCHAR *printer, TCHAR *port, WORD cap, TCHAR *key) +{ + BYTE boolval; + /* DeviceCapabilities doesn't always return 1 for true...just nonzero */ + boolval = (BYTE) (DeviceCapabilities(printer, port, cap, NULL, NULL) ? 1 : 0); + printf("%s: %s\n", key, boolval ? "TRUE" : "FALSE"); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, key, REG_BINARY, &boolval, sizeof(boolval)); +} + +void map_generic_dword(HANDLE ph, TCHAR *printer, TCHAR *port, WORD cap, TCHAR *key) +{ + DWORD dword; + + dword = DeviceCapabilities(printer, port, cap, NULL, NULL); + if ((DWORD) -1 == dword) + return; + + printf("%s: %d\n", key, dword); + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, key, REG_DWORD, (BYTE *) &dword, sizeof(dword)); +} + +void map_generic_multi_sz(HANDLE ph, TCHAR *printer, TCHAR *port, WORD cap, TCHAR *key, int size) +{ + TCHAR *strings_in; + TCHAR *strings_out, *strings_cur; + DWORD num_items, i; + + num_items = DeviceCapabilities(printer, port, cap, NULL, NULL); + if ((DWORD) -1 == num_items) + return; + strings_in = malloc(num_items * size); + strings_out = calloc(num_items, size); + num_items = DeviceCapabilities(printer, port, cap, strings_in, NULL); + printf("%s:\n", key); + for (i=0, strings_cur = strings_out; i < num_items; i++) { + _tcsncpy(strings_cur, &strings_in[i*size], size); + printf("\t%s\n", strings_cur); + strings_cur += _tcslen(strings_cur) + 1; + } + + SetPrinterDataEx(ph, SPLDS_DRIVER_KEY, key, REG_MULTI_SZ, strings_out, + (strings_cur - strings_out + 1) * sizeof(TCHAR)); + + free(strings_in); + free(strings_out); +} + +int main(int argc, char *argv[]) +{ + HANDLE ph; + BYTE *driver_info; + DWORD needed; + TCHAR *printer; + TCHAR *port = SAMBA_PORT; + PRINTER_DEFAULTS admin_access = {NULL, NULL, PRINTER_ACCESS_ADMINISTER}; + PRINTER_INFO_7 publish = {NULL, DSPRINT_PUBLISH}; + + if (argc < 2) { + printf("Usage: %s <printername>\n", argv[0]); + return -1; + } + + printer = argv[1]; + + if (!(OpenPrinter(printer, &ph, &admin_access))) { + printf("OpenPrinter failed, error = %s\n", PrintLastError()); + return -1; + } + + GetPrinterDriver(ph, NULL, 1, NULL, 0, &needed); + if (!needed) { + printf("GetPrinterDriver failed, error = %s\n", PrintLastError()); + ClosePrinter(ph); + return -1; + } + driver_info = malloc(needed); + if (!(GetPrinterDriver(ph, NULL, 1, driver_info, needed, &needed))) { + printf("GetPrinterDriver failed, error = %s\n", PrintLastError()); + ClosePrinter(ph); + return -1; + } + + map_generic_multi_sz(ph, printer, port, DC_BINNAMES, _T("printBinNames"), 24); + map_generic_boolean(ph, printer, port, DC_COLLATE, _T("printCollate")); + map_generic_dword(ph, printer, port, DC_COPIES, _T("printMaxCopies")); + map_generic_dword(ph, printer, port, DC_DRIVER, _T("driverVersion")); + map_generic_boolean(ph, printer, port, DC_DUPLEX, _T("printDuplexSupported")); + map_extents(ph, printer, port); + map_resolution(ph, printer, port); + map_orientation(ph, printer, port); + map_generic_multi_sz(ph, printer, port, DC_PAPERNAMES, _T("printMediaSupported"), 64); +#if (WINVER >= 0x0500) + map_generic_boolean(ph, printer, port, DC_COLORDEVICE, _T("printColor")); + map_generic_multi_sz(ph, printer, port, DC_PERSONALITY, _T("printLanguage"), 64); + map_generic_multi_sz(ph, printer, port, DC_MEDIAREADY, _T("printMediaReady"),64); + map_generic_dword(ph, printer, port, DC_PRINTERMEM, _T("printMemory")); + map_generic_dword(ph, printer, port, DC_PRINTRATE, _T("printRate")); + map_printrateunit(ph, printer, port); +#ifdef DC_STAPLE + map_generic_boolean(ph, printer, port, DC_STAPLE, _T("printStaplingSupported")); +#endif +#ifdef DC_PRINTRATEPPM + map_generic_dword(ph, printer, port, DC_PRINTRATEPPM, _T("printPagesPerMinute")); +#endif +#endif + SetPrinter(ph, 7, (BYTE *) &publish, 0); + ClosePrinter(ph); + return 0; +} diff --git a/examples/printing/readme.prtpub b/examples/printing/readme.prtpub new file mode 100644 index 0000000000..319ce605c3 --- /dev/null +++ b/examples/printing/readme.prtpub @@ -0,0 +1,12 @@ +prtpub.c contains a program which, when compiled with Visual C, can +download a driver for a printer, query the capabilities of the driver, +then write back the DsDriver keys necessary to publish all the fields +of a printer in the directory. After writing back the fields, it issues +a SetPrinter with info level 7, telling the server to publish the +printer. + +It also writes the fields to stdout. + +In order to be distributed, it should be compiled using DLLs for C runtime. + +The program takes the UNC name of a printer as the only argument. diff --git a/examples/printing/smbprint b/examples/printing/smbprint new file mode 100755 index 0000000000..3d4b53f850 --- /dev/null +++ b/examples/printing/smbprint @@ -0,0 +1,176 @@ +#!/bin/bash + +# This script is an input filter for printcap printing on a unix machine. It +# uses the smbclient program to print the file to the specified smb-based +# server and service. +# For example you could have a printcap entry like this +# +# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint +# +# which would create a unix printer called "smb" that will print via this +# script. You will need to create the spool directory /usr/spool/smb with +# appropriate permissions and ownerships for your system. + +# Set these to the server and service you wish to print to +# In this example I have a WfWg PC called "lapland" that has a printer +# exported called "printer" with no password. + +# +# Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton) +# so that the server, service, and password can be read from +# a /usr/var/spool/lpd/PRINTNAME/.config file. +# +# Script further modified by Richard Sharpe to fix some things. +# Get rid of the -x on the first line, and add parameters +# +# -t now causes translate to be used when sending files +# +# Further modifications by Alfred Perlstein to fix some problems and +# improve the quality of the code (3-Dec-2001). +# +# More hacking by Richard Sharpe to improve portability. 9-Dec-2001. +# +# In order for this to work the /etc/printcap entry must include an +# accounting file (af=...): +# +# cdcolour:\ +# :cm=CD IBM Colorjet on 6th:\ +# :sd=/var/spool/lpd/cdcolour:\ +# :af=/var/spool/lpd/cdcolour/acct:\ +# :if=/usr/local/etc/smbprint:\ +# :mx=0:\ +# :lp=/dev/null: +# +# The /usr/var/spool/lpd/PRINTNAME/.config file should contain: +# server=PC_SERVER +# service=PR_SHARENAME +# password="password" +# +# E.g. +# server=PAULS_PC +# service=CJET_371 +# password="" + +#smbclient=/usr/pkg/bin/smbclient +# Assume that smbclient will be in the same place as smbprint + +smbclient="`dirname $0`/smbclient" + +# +# The last parameter to the filter is the accounting file name. +# Extract the directory name from the file name. +# Concat this with /.config to get the config file. +# +TRANS=0 +eval acct_file=\${$#} +spool_dir=`dirname $acct_file` +config_file=$spool_dir/.config + +# Should read the following variables set in the config file: +# server +# service +# password +# username (optional) +# IP (optional) +# debug (optional) +# debugsmb (optional) +# debugfile (optional) +. $config_file + +if [ "x$password" = "x" ] ; then + password="-N" +fi + +if [ "x$username" == "x" ] ; then + username="$server"; +fi + +while test $# -gt 0; do + case "$1" in + -t) + TRANS=1 + ;; + + *) # Bad Parameters, ignore them ... + ;; + esac + shift +done + +command="print - ;" +if [ $TRANS -eq 1 ]; then + command="translate;$command"; +fi + +## +## Some security checks on the logfile if we are using it +## +## make the directory containing the logfile is necessary +## and set the permissions to be rwx for owner only +## + +debugfile="/tmp/smb-print/logfile" +logdir=`dirname $debugfile` +if [ ! -d $logdir ]; then + mkdir -m 0700 $logdir +fi + +## +## check ownership. If I don't own it refuse to +## create the logfile +## +if [ ! -O $logdir ]; then + echo "user running script does not own $logdir. Ignoring any debug options." + debug="" +fi + +touch $debugfile +if [ -h $debugfile ]; then + echo "$debugful is a symlink. Turning off debugging!" + debug="" +fi + +## +## We should be safe at this point to create the log file +## without fear of a symlink attack -- move on to more script work. +## + +if [ "x$debug" = "x" ] ; then + debugfile=/dev/null debugargs= +else + if [ $debug -eq 0 ] ; then + debugfile=/dev/null debugargs= + else + set -x; exec >>$debugfile 2>&1 + debugargs="$debugfile." + #[ "x$debugsmb" == "x" ] || debugargs="$debugargs -d $debugsmb" + fi +fi + +if [ "x$smbconf" != "x" ]; then + + smbconf="-s $smbconf" + +fi + +if [ "x$IP" != "x" ]; then + + IP="-I $IP" + +fi + +if [ "x$debugargs" != "x" ]; then + + debugargs="-l $debugargs" + +fi + +$smbclient \ + "\\\\$server\\$service" \ + $password \ + $smbconf \ + $IP \ + $debugargs \ + -U $username \ + -c "$command" +# diff --git a/examples/printing/smbprint.sysv b/examples/printing/smbprint.sysv new file mode 100644 index 0000000000..11fea21441 --- /dev/null +++ b/examples/printing/smbprint.sysv @@ -0,0 +1,52 @@ +#!/bin/sh +# +# @(#) smbprint.sysv version 1.0 Ross Wakelin <r.wakelin@march.co.uk> +# +# Version 1.0 13 January 1995 +# modified from the original smbprint (bsd) script +# +# this script is a System 5 printer interface script. It +# uses the smbclient program to print the file to the specified smb-based +# server and service. +# +# To add this to your lp system, copy this file into your samba directory +# (the example here is /opt/samba), modify the server and service variables +# and then execute the following command (as root) +# +# lpadmin -punixprintername -v/dev/null -i/opt/samba/smbprint +# +# where unixprintername is the name that the printer will be known as +# on your unix box. +# +# the script smbprint will be copied into your printer administration +# directory (/usr/lib/lp or /etc/lp) as a new interface +# (interface/unixprintername) +# Then you have to enable unixprintername and accept unixprintername +# +# This script will then be called by the lp service to print the files +# This script will have 6 or more parameters passed to it by the lp service. +# The first five will contain details of the print job, who queued it etc, +# while parameters 6 onwards are a list of files to print. We just +# cat these at the samba client. +# +# Set these to the server and service you wish to print to +# In this example I have a WfWg PC called "lapland" that has a printer +# exported called "printer" with no password. +# +# clear out the unwanted parameters +shift;shift;shift;shift;shift +# now the argument list is just the files to print + +server=admin +service=hplj2 +password="" + +( +# NOTE You may wish to add the line `echo translate' if you want automatic +# CR/LF translation when printing. + echo translate + echo "print -" + cat $* +) | /opt/samba/smbclient "\\\\$server\\$service" $password -N > /dev/null +exit $? + diff --git a/examples/scripts/debugging/linux/backtrace b/examples/scripts/debugging/linux/backtrace new file mode 100644 index 0000000000..2ea6a4d00a --- /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/solaris/README b/examples/scripts/debugging/solaris/README new file mode 100644 index 0000000000..9e336805e5 --- /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 0000000000..82c49efdf6 --- /dev/null +++ b/examples/scripts/debugging/solaris/solaris-oops.sh @@ -0,0 +1,55 @@ +#!/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 0000000000..0c21a94103 --- /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 "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/mount/mount.smbfs b/examples/scripts/mount/mount.smbfs new file mode 100644 index 0000000000..3b57bc5141 --- /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/printing/cups/smbaddprinter.pl b/examples/scripts/printing/cups/smbaddprinter.pl new file mode 100755 index 0000000000..aee2020bfc --- /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 0000000000..23adeb719c --- /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/shares/perl/modify_samba_config.pl b/examples/scripts/shares/perl/modify_samba_config.pl new file mode 100755 index 0000000000..20b613aba8 --- /dev/null +++ b/examples/scripts/shares/perl/modify_samba_config.pl @@ -0,0 +1,168 @@ +#!/usr/bin/perl + +###################################################################### +## +## Simple add/delete/change share command script for Samba +## +## Copyright (C) Gerald Carter 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/>. +## +###################################################################### + +use POSIX qw(tmpnam); + +## +## local variables +## +my $delete_mode = undef; +my $add_mode = undef; +my $tmp_file_name = undef; + + +## check for correct parameters +if ($#ARGV == 1) { + $delete_mode = 1; +} +elsif ($#ARGV == 4) { + $add_mode = 1; +} +else { + print "Usage: $0 configfile share [path] [comment]\n"; + exit -1; +} + +## first param is always the config file +open (CONFIGFILE, "$ARGV[0]") || die "Unable to open $ARGV[0] for reading!\n"; + +## FIXME!! Right now we throw away all comments in the file. +while (<CONFIGFILE>) { + + chomp($_); + + ## eat leading whitespace + $_ =~ s/^\s*//; + + ## eat trailing whitespace + $_ =~ s/\s*$//; + + + ## throw away comments + next if (($_ =~ /^#/) || ($_ =~ /^;/)); + + ## set the current section name for storing the hash + if ($_ =~ /^\[.*\]$/) { + + $_ = substr($_, 1, length($_)-2); + + if ( length($_) ) { + $section = $_; + } + else { + print "Bad Section Name - no closing ]\n"; + exit -1; + } + + next; + } + + ## check for a param = value + if ($_ =~ /=/) { + ($param, $value) = split (/=/, $_,2); + $param =~ s/./\l$&/g; + $param =~ s/\s+//g; + $value =~ s/^\s+//; + + $config{$section}{$param} = $value; + + next; + } + + ## should have a hash of hashes indexed by section name +} +close (CONFIGFILE); + +## +## We have the smb.conf in our hash of hashes now. +## Add or delete +## +if ($add_mode) { + $config{$ARGV[1]}{'path'} = $ARGV[2]; + $config{$ARGV[1]}{'comment'} = $ARGV[3]; + $config{$ARGV[1]}{'max connections'} = $ARGV[4]; +} +elsif ($delete_mode) { + delete $config{$ARGV[1]}; +} + +## +## Print the resulting configuration +## +#do { +# $tmp_file_name = tmpnam(); +# print "Using temporary file - $tmp_file_name\n"; +#} while (!sysopen(TMP, $tmp_file_name, O_RDWR|O_CREAT|O_EXCL)); +$tmp_file_name = tmpnam(); +open (TMP, ">$tmp_file_name") || die "Unable to open temporary file for writing!\n"; + +PrintConfigFile(TMP); + +## now overwrite the original config file +close (TMP); +system ("cp -pf $ARGV[0] $ARGV[0].bak"); +system ("cp -pf $tmp_file_name $ARGV[0]"); +unlink $tmp_file_name; + + +exit 0; + + + + + +####################################################################################### +## PrintConfigFile() +## +sub PrintConfigFile { + my ($output) = @_; + + ## print the file back out, beginning with the global section + print $output "#\n# Generated by $0\n#\n"; + + PrintSection ($output, 'global', $config{'global'}); + + foreach $section (keys %config) { + + if ("$section" ne "global") { + print $output "## Section - [$section]\n"; + PrintSection ($output, $section, $config{$section}); + } + } + + print $output "#\n# end of generated smb.conf\n#\n"; +} + +####################################################################################### +## PrintSection() +## +sub PrintSection { + my ($outfile, $name, $section) = @_; + + print $outfile "[$name]\n"; + foreach $param (keys %$section) { + print $outfile "\t$param".' 'x(25-length($param)). " = $$section{$param}\n"; + } + print $outfile "\n"; + +} diff --git a/examples/scripts/shares/python/SambaConfig.py b/examples/scripts/shares/python/SambaConfig.py new file mode 100644 index 0000000000..3d4a47398c --- /dev/null +++ b/examples/scripts/shares/python/SambaConfig.py @@ -0,0 +1,314 @@ +import sys, string, SambaParm +from smbparm import parm_table + +###################################################################### +## +## smb.conf parser class +## +## Copyright (C) Gerald Carter 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/>. +## +###################################################################### + + +##################################################################### +## multi line Samba comment +class SambaComment: + + def __init__( self, comment ): + self.comment = comment + + def Dump( self, stream, whitespace=None ): + if not self.comment: + return + for line in self.comment: + if whitespace: + stream.write( whitespace ) + stream.write( line ) + stream.write( "\n" ) + + +##################################################################### +## string smb.conf parms +class SambaParameter : + + ## indexs into the parm table tuples + DisplayName = 0 + ObjectType = 1 + DefaultValue = 2 + Scope = 3 + + ## Stores a key into the parm_table and creates an + ## SambaParmXXX object to store the value + def __init__( self, name, value, comment=None ): + self.key = string.upper(string.strip(name)) + self.comment = None + assert parm_table.has_key( self.key ), "Bad parameter name! [%s]" % name + self.parm = parm_table[self.key][self.ObjectType]( value ) + if comment : + self.comment = SambaComment( comment ) + + #if not self.parm.valid: + # self.parm.SetValue( parm_table[self.key][self.DefaultValue] ) + + ## simple test for global or service parameter scope + def isGlobalParm( self ) : + return parm_table[self.key][Scope] + + ## dump <the parameter to stdout + def Dump( self, stream ): + if self.comment: + self.comment.Dump( stream, "\t" ) + stream.write( "\t%s = %s\n" % ( parm_table[self.key][self.DisplayName], self.parm.StringValue() )) + + +##################################################################### +## Class for parsing and modifying Smb.conf +class SambaConf: + + def __init__( self ): + self.services = {} + self.valid = True + self.services["GLOBAL"] = {} + self.services_order = [] + + + ## always return a non-empty line of input or None + ## if we hit EOF + def ReadLine( self, stream ): + result = None + input_str = None + + while True: + input_str = stream.readline() + + ## Are we done with the file ? + + if len(input_str) == 0: + return result + + ## we need one line of valid input at least + ## continue around the loop again if the result + ## string is empty + + input_str = string.strip( input_str ) + if len(input_str) == 0: + if not result: + continue + else: + return result + + ## we have > 1` character so setup the result + if not result: + result = "" + + ## Check for comments -- terminated by \n -- no continuation + + if input_str[0] == '#' or input_str[0] == ';' : + result = input_str + break + + ## check for line continuation + + if input_str[-1] == "\\" : + result += input_str[0:-1] + contine + + ## otherwise we have a complete line + result += input_str + break + + return result + + ## convert the parameter name to a form suitable as a dictionary key + def NormalizeParamName( self, param ): + return string.upper( string.join(string.split(param), "") ) + + ## Open the file and parse it into a services dictionary + ## if possible + def ReadConfig( self, filename ): + self.filename = filename + + try: + fconfig = open( filename, "r" ) + except IOError: + self.valid = False + return + + section_name = None + + ## the most recent seen comment is stored as an array + current_comment = [] + + while True: + + str = self.ReadLine( fconfig ) + if not str: + break + + ## Check for comments + if str[0] == '#' or str[0] == ';' : + current_comment.append( str ) + continue + + ## look for a next section name + if str[0]=='[' and str[-1]==']' : + section_name = str[1:-1] + self.AddService( section_name, current_comment ) + current_comment = [] + continue + + str_list = string.split( str, "=" ) + + if len(str_list) != 2 : + continue + + if not section_name : + print "parameter given without section name!" + break + + param = self.NormalizeParamName( str_list[0] ) + value = string.strip(str_list[1]) + + self.SetServiceOption( section_name, param, value, current_comment ) + self.dirty = False + + ## reset the comment strinf if we have one + current_comment = [] + + fconfig.close() + + ## Add a parameter to the global section + def SetGlobalOption( self, param, value, comment=None ) : + self.SetServiceOption( "GLOBAL", param, value, comment ) + + ## Add a parameter to a specific service + def SetServiceOption( self, servicename, param, value, comment=None ) : + service = string.upper(servicename) + parm = self.NormalizeParamName(param) + self.services[service]['_order_'].append( parm ) + self.services[service][parm] = SambaParameter( parm, value, comment ) + self.dirty = True + + ## remove a service from the config file + def DelService( self, servicename ) : + service = string.upper(servicename) + self.services[service] = None + self.dirty = True + + ## remove a service from the config file + def AddService( self, servicename, comment=None ) : + service = string.upper(servicename) + + self.services[service] = {} + self.services[service]['_order_'] = [] + + if ( comment ): + self.services[service]['_comment_'] = SambaComment( comment ) + + self.services_order.append( service ) + + self.dirty = True + + def isService( self, servicename ): + service = string.upper(servicename) + return self.services.has_key( service ) + + ## dump a single service to stream + def DumpService( self, stream, servicename ): + + ## comments first + if self.services[servicename].has_key( '_comment_' ): + self.services[servicename]['_comment_'].Dump( stream ) + + ## section header + stream.write( "[%s]\n" % (servicename) ) + + ## parameter = value + for parm in self.services[servicename]['_order_']: + self.services[servicename][parm].Dump(stream) + + ## dump the config to stream + def Dump( self, stream ): + self.DumpService( stream, "GLOBAL" ) + stream.write("\n") + + for section in self.services_order: + ## already handled the global section + if section == "GLOBAL": + continue + + ## check for deleted sections ## + if not self.services[section]: + continue + + self.DumpService( stream, section ) + stream.write( "\n" ) + + ## write out any changes to disk + def Flush( self ): + if not self.dirty: + return + + try: + fconfig = open( self.filename, "w" ) + except IOError: + sys.stderr.write( "ERROR!\n" ) + return 1 + + self.Dump( fconfig ) + fconfig.close() + return 0 + + def Services( self ): + service_list = [] + for section in self.services.keys(): + service_list.append( section ) + + return service_list + + def NumServices( self ): + return len(self.Services()) + + def Write( self, filename ): + self.filename = filename + self.valid = True + + if not self.dirty: + return + + self.Flush() + + + +###################################################################### +## Unit tests +###################################################################### + +if __name__ == "__main__" : + + x = SambaConf( ) + x.ReadConfig( sys.argv[1] ) + if not x.valid : + print "Bad file!" + sys.exit(1) + + x.Dump( sys.stdout ) + + + +## end of SambaConfig.py ###################################################### +############################################################################### + diff --git a/examples/scripts/shares/python/SambaParm.py b/examples/scripts/shares/python/SambaParm.py new file mode 100644 index 0000000000..82c99c84ac --- /dev/null +++ b/examples/scripts/shares/python/SambaParm.py @@ -0,0 +1,83 @@ +###################################################################### +## +## smb.conf parameter classes +## +## Copyright (C) Gerald Carter 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/>. +## +###################################################################### + +import string + +##################################################################### +## Base class for Samba smb.conf parameters +class SambaParm : + def __init__( self ) : + pass + + def StringValue( self ) : + return self.value + +##################################################################### +## Boolean smb,conf parm +class SambaParmBool( SambaParm ): + def __init__( self, value ) : + x = string.upper(value) + self.valid = True + + if x=="YES" or x=="TRUE" or x=="1": + self.value = True + elif x=="NO" or x=="FALSE" or x=="0": + self.value = False + else: + self.valid = False + return self + + def SetValue( self, value ) : + x = string.upper(value) + self.valid = True + + if x=="YES" or x=="TRUE" or x=="1": + self.value = True + elif x=="NO" or x=="FALSE" or x=="0": + self.value = False + else: + self.valid = False + return + + def StringValue( self ) : + if self.value : + return "yes" + else: + return "no" + +##################################################################### +## Boolean smb,conf parm (inverts) +class SambaParmBoolRev( SambaParmBool ) : + def __init__( self, value ): + SambaParmBool.__init__( self, value ) + if self.valid : + self.value = not self.value + + +##################################################################### +## string smb.conf parms +class SambaParmString( SambaParm ): + def __init__( self, value ): + self.value = value + self.valid = True + + + diff --git a/examples/scripts/shares/python/generate_parm_table.py b/examples/scripts/shares/python/generate_parm_table.py new file mode 100755 index 0000000000..1d2c5f246c --- /dev/null +++ b/examples/scripts/shares/python/generate_parm_table.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python +###################################################################### +## +## Generate parameter dictionary from param/loadparm.c +## +## Copyright (C) Gerald Carter 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/>. +## +###################################################################### + +import re, string, sys, commands + +HEADER = """###################################################################### +## +## autogenerated file of smb.conf parameters +## generate_parm_table <..../param/loadparm.c> +## +## Copyright (C) Gerald Carter 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/>. +## +###################################################################### + +from SambaParm import SambaParmString, SambaParmBool, SambaParmBoolRev + +## boolean defines for parm_table +P_LOCAL = 0 +P_GLOBAL = 1 + +""" + +FOOTER = """##### end of smbparm.y ########################################## +#################################################################""" + +TESTPARM = "/usr/bin/testparm" + +## fields in Samba's parameter table +displayName = 0 +type = 1 +scope = 2 +variable = 3 +flags = 6 + +parm_table = {} +var_table = {} +def_values = {} +obj_table = { + 'P_BOOL' : 'SambaParmBool', + 'P_BOOLREV' : 'SambaParmBoolRev', + 'P_STRING' : 'SambaParmString', + 'P_USTRING' : 'SambaParmString', + 'P_GSTRING' : 'SambaParmString', + 'P_LIST' : 'SambaParmString', + 'P_ENUM' : 'SambaParmString', + 'P_CHAR' : 'SambaParmString', + 'P_OCTAL' : 'SambaParmString', + 'P_INTEGER' : 'SambaParmString', +} + +###################################################################### +## BEGIN MAIN CODE ## +###################################################################### + +## First thing is to build the dictionary of parmeter names ## +## based on the output from testparm ## + +cmd = "/usr/bin/testparm -s -v /dev/null" +( status, testparm_output ) = commands.getstatusoutput( cmd ) +if status: + sys.stderr.write( "Failed to execute testparm!\n%s\n" % testparm_output ) + + +## break the output into a list ## + +lines = string.split( testparm_output, "\n" ) + +## loop through list -- parameters in testparm output have ## +## whitespace at the beginning of the line ## + +pattern = re.compile( "^\s+" ) +for input_str in lines: + if not pattern.search( input_str ): + continue + input_str = string.strip( input_str ) + parts = string.split( input_str, "=" ) + parts[0] = string.strip( parts[0] ) + parts[1] = string.strip( parts[1] ) + key = string.upper( string.join(string.split(parts[0]), "") ) + new = parts[1].replace('\\', '\\\\') + def_values[key] = new + +## open loadparm.c and get the entire list of parameters ## +## including synonums ## + +if len(sys.argv) != 2: + print "Usage: %s <.../param/loadparm.c>" % ( sys.argv[0] ) + sys.exit( 1 ) + +try: + fconfig = open( sys.argv[1], "r" ) +except IOError: + print "%s does not exist!" % sys.argv[1] + sys.exit (1) + +## Loop through loadparm.c -- all parameters are either ## +## P_LOCAL or P_GLOBAL ## + +synonyms = [] +pattern = re.compile( '{".*P_[GL]' ) +while True: + input_str= fconfig.readline() + if len(input_str) == 0 : + break + input_str= string.strip(input_str) + + ## see if we have a patch for a parameter definition ## + + parm = [] + if pattern.search( input_str) : + + ## strip the surrounding '{.*},' ## + + input_str= input_str[1:-2] + parm = string.split(input_str, ",") + + ## strip the ""'s and upper case ## + + name = (string.strip(parm[displayName])[1:-1]) + key = string.upper( string.join(string.split(name), "") ) + var_name = string.strip( parm[variable] ) + + + ## try to catch synonyms -- if the parameter was not reported ## + ## by testparm, then save it and come back after we will out ## + ## the variable list ## + + if not def_values.has_key( key ): + synonyms.append( input_str) + continue + + + var_table[var_name] = key + + parmType = string.strip(parm[type]) + + parm_table[key] = [ name , string.strip(parm[type]), string.strip(parm[scope]), def_values[key] ] + +## Deal with any synonyms ## + +for input_str in synonyms: + parm = string.split(input_str, ",") + name = (string.strip(parm[displayName])[1:-1]) + key = string.upper( string.join(string.split(name), "") ) + var_name = string.strip( parm[variable] ) + + ## if there's no pre-existing key, then testparm doesn't know about it + if not var_table.has_key( var_name ): + continue + + ## just make a copy + parm_table[key] = parm_table[var_table[var_name]][:] + # parm_table[key][1] = parm[1] + parm_table[key][1] = string.strip(parm[1]) + +## ## +## print out smbparm.py ## +## ## + +try: + smbparm = open ( "smbparm.py", "w" ) +except IOError: + print "Cannot write to smbparm.py" + sys.exit( 1 ) + +smbparm.write( HEADER ) +smbparm.write( "parm_table = {\n" ) + +for x in parm_table.keys(): + key = "\"%s\"" % x + smbparm.write("\t%-25s: (\"%s\", %s, %s, \"%s\"),\n" % ( key, parm_table[x][0], + obj_table[parm_table[x][1]], parm_table[x][2], parm_table[x][3] )) + +smbparm.write( "}\n" ) + +smbparm.write( FOOTER ) +smbparm.write( "\n" ) + +sys.exit(0) + + +## ## +## cut-n-paste area ## +## ## + +for x in parm_table.keys(): + if def_values.has_key( x ): + parm_table[x].append( def_values[x] ) + else: + parm_table[x].append( "" ) diff --git a/examples/scripts/shares/python/modify_samba_config.py b/examples/scripts/shares/python/modify_samba_config.py new file mode 100755 index 0000000000..88b3fcb394 --- /dev/null +++ b/examples/scripts/shares/python/modify_samba_config.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +###################################################################### +## +## Simple add/delete/change share command script for Samba +## +## Copyright (C) Gerald Carter 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/>. +## +###################################################################### + +import sys, os +from SambaConfig import SambaConf + + +## ## +## check the command line args ## +## ## +delete_mode = False +if len(sys.argv) == 3: + delete_mode = True + print "Deleting share..." +elif len(sys.argv) == 5: + print "Adding/Updating share..." +else: + print "Usage: %s configfile share [path] [comments]" % sys.argv[0] + sys.exit(1) + + +## ## +## read and parse the config file ## +## ## + +confFile = SambaConf() + +confFile.ReadConfig( sys.argv[1] ) +if not confFile.valid: + exit( 1 ) + +if delete_mode: + if not confFile.isService( sys.argv[2] ): + sys.stderr.write( "Asked to delete non-existent service! [%s]\n" % sys.argv[2] ) + sys.exit( 1 ) + + confFile.DelService( sys.argv[2] ) +else: + ## make the path if it doesn't exist. Bail out if that fails + if ( not os.path.isdir(sys.argv[3]) ): + try: + os.makedirs( sys.argv[3] ) + os.chmod( sys.argv[3], 0777 ) + except os.error: + sys.exit( 1 ) + + ## only add a new service -- if it already exists, then + ## just set the options + if not confFile.isService( sys.argv[2] ): + confFile.AddService( sys.argv[2], ['##', '## Added by modify_samba_config.py', '##'] ) + confFile.SetServiceOption( sys.argv[2], "path", sys.argv[3] ) + confFile.SetServiceOption( sys.argv[2], "comment", sys.argv[4] ) + confFile.SetServiceOption( sys.argv[2], "read only", "no" ) + +ret = confFile.Flush() + +sys.exit( ret ) + diff --git a/examples/scripts/shares/python/smbparm.py b/examples/scripts/shares/python/smbparm.py new file mode 100644 index 0000000000..73637a7095 --- /dev/null +++ b/examples/scripts/shares/python/smbparm.py @@ -0,0 +1,373 @@ +###################################################################### +## +## autogenerated file of smb.conf parameters +## generate_parm_table <..../param/loadparm.c> +## +## Copyright (C) Gerald Carter 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/>. +## +###################################################################### + +from SambaParm import SambaParmString, SambaParmBool, SambaParmBoolRev + +## boolean defines for parm_table +P_LOCAL = 0 +P_GLOBAL = 1 + +parm_table = { + "PRELOADMODULES" : ("preload modules", SambaParmString, P_GLOBAL, ""), + "ONLYGUEST" : ("guest only", SambaParmBool, P_LOCAL, "No"), + "PRIVATEDIR" : ("private dir", SambaParmString, P_GLOBAL, "/etc/samba/private"), + "HIDESPECIALFILES" : ("hide special files", SambaParmBool, P_LOCAL, "No"), + "WINBINDENUMUSERS" : ("winbind enum users", SambaParmBool, P_GLOBAL, "Yes"), + "TIMESTAMPLOGS" : ("debug timestamp", SambaParmBool, P_GLOBAL, "Yes"), + "LDAPPASSWDSYNC" : ("ldap passwd sync", SambaParmString, P_GLOBAL, "no"), + "READBMPX" : ("read bmpx", SambaParmBool, P_GLOBAL, "No"), + "PASSWORDSERVER" : ("password server", SambaParmString, P_GLOBAL, "*"), + "COPY" : ("copy", SambaParmString, P_LOCAL, ""), + "MAXXMIT" : ("max xmit", SambaParmString, P_GLOBAL, "16644"), + "MINPRINTSPACE" : ("min print space", SambaParmString, P_LOCAL, "0"), + "CASESENSITIVE" : ("case sensitive", SambaParmString, P_LOCAL, "Auto"), + "LDAPIDMAPSUFFIX" : ("ldap idmap suffix", SambaParmString, P_GLOBAL, ""), + "NAMECACHETIMEOUT" : ("name cache timeout", SambaParmString, P_GLOBAL, "660"), + "MAPARCHIVE" : ("map archive", SambaParmBool, P_LOCAL, "Yes"), + "LANMANAUTH" : ("lanman auth", SambaParmBool, P_GLOBAL, "Yes"), + "NETBIOSSCOPE" : ("netbios scope", SambaParmString, P_GLOBAL, ""), + "MAXREPORTEDPRINTJOBS" : ("max reported print jobs", SambaParmString, P_LOCAL, "0"), + "CREATEMODE" : ("create mask", SambaParmString, P_LOCAL, "0744"), + "READLIST" : ("read list", SambaParmString, P_LOCAL, ""), + "WINBINDNESTEDGROUPS" : ("winbind nested groups", SambaParmBool, P_GLOBAL, "No"), + "COMMENT" : ("comment", SambaParmString, P_LOCAL, ""), + "PRINTER" : ("printer name", SambaParmString, P_LOCAL, ""), + "LMANNOUNCE" : ("lm announce", SambaParmString, P_GLOBAL, "Auto"), + "SYSLOGONLY" : ("syslog only", SambaParmBool, P_GLOBAL, "No"), + "LMINTERVAL" : ("lm interval", SambaParmString, P_GLOBAL, "60"), + "MANGLINGMETHOD" : ("mangling method", SambaParmString, P_GLOBAL, "hash2"), + "PROFILEACLS" : ("profile acls", SambaParmBool, P_LOCAL, "No"), + "LDAPGROUPSUFFIX" : ("ldap group suffix", SambaParmString, P_GLOBAL, ""), + "MAPTOGUEST" : ("map to guest", SambaParmString, P_GLOBAL, "Never"), + "NULLPASSWORDS" : ("null passwords", SambaParmBool, P_GLOBAL, "No"), + "ONLYUSER" : ("only user", SambaParmBool, P_LOCAL, "No"), + "UTMP" : ("utmp", SambaParmBool, P_GLOBAL, "No"), + "DONTDESCEND" : ("dont descend", SambaParmString, P_LOCAL, ""), + "PRINTING" : ("printing", SambaParmString, P_LOCAL, "cups"), + "SOCKETOPTIONS" : ("socket options", SambaParmString, P_GLOBAL, "TCP_NODELAY"), + "CLIENTUSESPNEGO" : ("client use spnego", SambaParmBool, P_GLOBAL, "Yes"), + "USESPNEGO" : ("use spnego", SambaParmBool, P_GLOBAL, "Yes"), + "FAKEOPLOCKS" : ("fake oplocks", SambaParmBool, P_LOCAL, "No"), + "FORCECREATEMODE" : ("force create mode", SambaParmString, P_LOCAL, "00"), + "SETDIRECTORY" : ("set directory", SambaParmBoolRev, P_LOCAL, "No"), + "SMBPORTS" : ("smb ports", SambaParmString, P_GLOBAL, "445 139"), + "LOCKDIR" : ("lock directory", SambaParmString, P_GLOBAL, "/var/lib/samba"), + "BROWSEABLE" : ("browseable", SambaParmBool, P_LOCAL, "Yes"), + "WINSPROXY" : ("wins proxy", SambaParmBool, P_GLOBAL, "No"), + "FORCEGROUP" : ("force group", SambaParmString, P_LOCAL, ""), + "NTSTATUSSUPPORT" : ("nt status support", SambaParmBool, P_GLOBAL, "Yes"), + "EXEC" : ("preexec", SambaParmString, P_LOCAL, ""), + "DOMAINLOGONS" : ("domain logons", SambaParmBool, P_GLOBAL, "No"), + "TEMPLATESHELL" : ("template shell", SambaParmString, P_GLOBAL, "/bin/false"), + "USESENDFILE" : ("use sendfile", SambaParmBool, P_LOCAL, "No"), + "USEMMAP" : ("use mmap", SambaParmBool, P_GLOBAL, "Yes"), + "VALIDUSERS" : ("valid users", SambaParmString, P_LOCAL, ""), + "DEBUGLEVEL" : ("log level", SambaParmString, P_GLOBAL, "0"), + "PRINTCAPCACHETIME" : ("printcap cache time", SambaParmString, P_GLOBAL, "0"), + "SOCKETADDRESS" : ("socket address", SambaParmString, P_GLOBAL, "0.0.0.0"), + "FORCEDIRECTORYMODE" : ("force directory mode", SambaParmString, P_LOCAL, "00"), + "MSDFSROOT" : ("msdfs root", SambaParmBool, P_LOCAL, "No"), + "ROOTPREEXEC" : ("root preexec", SambaParmString, P_LOCAL, ""), + "WRITEOK" : ("read only", SambaParmBoolRev, P_LOCAL, "Yes"), + "MAXLOGSIZE" : ("max log size", SambaParmString, P_GLOBAL, "5000"), + "FORCESECURITYMODE" : ("force security mode", SambaParmString, P_LOCAL, "00"), + "VFSOBJECT" : ("vfs objects", SambaParmString, P_LOCAL, ""), + "CHECKPASSWORDSCRIPT" : ("check password script", SambaParmString, P_GLOBAL, ""), + "DELETEPRINTERCOMMAND" : ("deleteprinter command", SambaParmString, P_GLOBAL, ""), + "OSLEVEL" : ("os level", SambaParmString, P_GLOBAL, "20"), + "ENUMPORTSCOMMAND" : ("enumports command", SambaParmString, P_GLOBAL, ""), + "DELETEUSERFROMGROUPSCRIPT": ("delete user from group script", SambaParmString, P_GLOBAL, ""), + "IDMAPGID" : ("idmap gid", SambaParmString, P_GLOBAL, ""), + "PREEXECCLOSE" : ("preexec close", SambaParmBool, P_LOCAL, "No"), + "UTMPDIRECTORY" : ("utmp directory", SambaParmString, P_GLOBAL, ""), + "DOSFILEMODE" : ("dos filemode", SambaParmBool, P_LOCAL, "No"), + "LOGFILE" : ("log file", SambaParmString, P_GLOBAL, ""), + "WORKGROUP" : ("workgroup", SambaParmString, P_GLOBAL, "WORKGROUP"), + "DIRECTORYSECURITYMASK" : ("directory security mask", SambaParmString, P_LOCAL, "0777"), + "ENCRYPTPASSWORDS" : ("encrypt passwords", SambaParmBool, P_GLOBAL, "Yes"), + "PRINTABLE" : ("printable", SambaParmBool, P_LOCAL, "No"), + "MAXPROTOCOL" : ("max protocol", SambaParmString, P_GLOBAL, "NT1"), + "KERNELOPLOCKS" : ("kernel oplocks", SambaParmBool, P_GLOBAL, "Yes"), + "NETBIOSALIASES" : ("netbios aliases", SambaParmString, P_GLOBAL, ""), + "ANNOUNCEAS" : ("announce as", SambaParmString, P_GLOBAL, "NT"), + "DIRECTORYMASK" : ("directory mask", SambaParmString, P_LOCAL, "0755"), + "MAPSYSTEM" : ("map system", SambaParmBool, P_LOCAL, "No"), + "CHANGENOTIFYTIMEOUT" : ("change notify timeout", SambaParmString, P_GLOBAL, "60"), + "WINBINDTRUSTEDDOMAINSONLY": ("winbind trusted domains only", SambaParmBool, P_GLOBAL, "No"), + "SHUTDOWNSCRIPT" : ("shutdown script", SambaParmString, P_GLOBAL, ""), + "FOLLOWSYMLINKS" : ("follow symlinks", SambaParmBool, P_LOCAL, "Yes"), + "MAPHIDDEN" : ("map hidden", SambaParmBool, P_LOCAL, "No"), + "GROUP" : ("force group", SambaParmString, P_LOCAL, ""), + "DENYHOSTS" : ("hosts deny", SambaParmString, P_LOCAL, ""), + "WINBINDCACHETIME" : ("winbind cache time", SambaParmString, P_GLOBAL, "300"), + "DELETEVETOFILES" : ("delete veto files", SambaParmBool, P_LOCAL, "No"), + "DISABLESPOOLSS" : ("disable spoolss", SambaParmBool, P_GLOBAL, "No"), + "MAXCONNECTIONS" : ("max connections", SambaParmString, P_LOCAL, "0"), + "WRITERAW" : ("write raw", SambaParmBool, P_GLOBAL, "Yes"), + "SERVERSIGNING" : ("server signing", SambaParmString, P_GLOBAL, "No"), + "VOLUME" : ("volume", SambaParmString, P_LOCAL, ""), + "UNIXPASSWORDSYNC" : ("unix password sync", SambaParmBool, P_GLOBAL, "No"), + "OBEYPAMRESTRICTIONS" : ("obey pam restrictions", SambaParmBool, P_GLOBAL, "No"), + "PASSWDCHATTIMEOUT" : ("passwd chat timeout", SambaParmString, P_GLOBAL, "2"), + "USER" : ("username", SambaParmString, P_LOCAL, ""), + "HIDEDOTFILES" : ("hide dot files", SambaParmBool, P_LOCAL, "Yes"), + "ROOTPOSTEXEC" : ("root postexec", SambaParmString, P_LOCAL, ""), + "PROTOCOL" : ("max protocol", SambaParmString, P_GLOBAL, "NT1"), + "LDAPADMINDN" : ("ldap admin dn", SambaParmString, P_GLOBAL, ""), + "DNSPROXY" : ("dns proxy", SambaParmBool, P_GLOBAL, "Yes"), + "OS2DRIVERMAP" : ("os2 driver map", SambaParmString, P_GLOBAL, ""), + "QUEUERESUMECOMMAND" : ("queueresume command", SambaParmString, P_LOCAL, ""), + "SERVERSCHANNEL" : ("server schannel", SambaParmString, P_GLOBAL, "Auto"), + "IDMAPUID" : ("idmap uid", SambaParmString, P_GLOBAL, ""), + "WINBINDENABLELOCALACCOUNTS": ("winbind enable local accounts", SambaParmBool, P_GLOBAL, "No"), + "PRINTERNAME" : ("printer name", SambaParmString, P_LOCAL, ""), + "NTACLSUPPORT" : ("nt acl support", SambaParmBool, P_LOCAL, "Yes"), + "LOGLEVEL" : ("log level", SambaParmString, P_GLOBAL, "0"), + "STATCACHE" : ("stat cache", SambaParmBool, P_GLOBAL, "Yes"), + "LPQCACHETIME" : ("lpq cache time", SambaParmString, P_GLOBAL, "30"), + "LEVEL2OPLOCKS" : ("level2 oplocks", SambaParmBool, P_LOCAL, "Yes"), + "LARGEREADWRITE" : ("large readwrite", SambaParmBool, P_GLOBAL, "Yes"), + "LDAPREPLICATIONSLEEP" : ("ldap replication sleep", SambaParmString, P_GLOBAL, "1000"), + "SECURITYMASK" : ("security mask", SambaParmString, P_LOCAL, "0777"), + "LDAPUSERSUFFIX" : ("ldap user suffix", SambaParmString, P_GLOBAL, ""), + "NETBIOSNAME" : ("netbios name", SambaParmString, P_GLOBAL, "PANTHER"), + "LOCKSPINCOUNT" : ("lock spin count", SambaParmString, P_GLOBAL, "3"), + "OPLOCKS" : ("oplocks", SambaParmBool, P_LOCAL, "Yes"), + "MINWINSTTL" : ("min wins ttl", SambaParmString, P_GLOBAL, "21600"), + "HOMEDIRMAP" : ("homedir map", SambaParmString, P_GLOBAL, ""), + "REMOTEANNOUNCE" : ("remote announce", SambaParmString, P_GLOBAL, ""), + "PREFERREDMASTER" : ("preferred master", SambaParmString, P_GLOBAL, "Auto"), + "SECURITY" : ("security", SambaParmString, P_GLOBAL, "USER"), + "AUTHMETHODS" : ("auth methods", SambaParmString, P_GLOBAL, ""), + "ENABLERIDALGORITHM" : ("enable rid algorithm", SambaParmBool, P_GLOBAL, "Yes"), + "LPRMCOMMAND" : ("lprm command", SambaParmString, P_LOCAL, ""), + "KERNELCHANGENOTIFY" : ("kernel change notify", SambaParmBool, P_GLOBAL, "Yes"), + "LOGONSCRIPT" : ("logon script", SambaParmString, P_GLOBAL, ""), + "PRESERVECASE" : ("preserve case", SambaParmBool, P_LOCAL, "Yes"), + "UNIXCHARSET" : ("unix charset", SambaParmString, P_GLOBAL, "UTF-8"), + "FORCEPRINTERNAME" : ("force printername", SambaParmBool, P_LOCAL, "No"), + "LDAPFILTER" : ("ldap filter", SambaParmString, P_GLOBAL, "(uid"), + "DELETEREADONLY" : ("delete readonly", SambaParmBool, P_LOCAL, "No"), + "ABORTSHUTDOWNSCRIPT" : ("abort shutdown script", SambaParmString, P_GLOBAL, ""), + "DFREECOMMAND" : ("dfree command", SambaParmString, P_GLOBAL, ""), + "VETOFILES" : ("veto files", SambaParmString, P_LOCAL, ""), + "LOCKING" : ("locking", SambaParmBool, P_LOCAL, "Yes"), + "EASUPPORT" : ("ea support", SambaParmBool, P_LOCAL, "No"), + "MAXSMBDPROCESSES" : ("max smbd processes", SambaParmString, P_GLOBAL, "0"), + "HIDEFILES" : ("hide files", SambaParmString, P_LOCAL, ""), + "PASSWDCHATDEBUG" : ("passwd chat debug", SambaParmBool, P_GLOBAL, "No"), + "SMBPASSWDFILE" : ("smb passwd file", SambaParmString, P_GLOBAL, "/etc/samba/private/smbpasswd"), + "GETQUOTACOMMAND" : ("get quota command", SambaParmString, P_GLOBAL, ""), + "OPLOCKCONTENTIONLIMIT" : ("oplock contention limit", SambaParmString, P_LOCAL, "2"), + "DOMAINMASTER" : ("domain master", SambaParmString, P_GLOBAL, "Auto"), + "DELETESHARECOMMAND" : ("delete share command", SambaParmString, P_GLOBAL, ""), + "INVALIDUSERS" : ("invalid users", SambaParmString, P_LOCAL, ""), + "POSIXLOCKING" : ("posix locking", SambaParmBool, P_LOCAL, "Yes"), + "INCLUDE" : ("include", SambaParmString, P_LOCAL, ""), + "ALGORITHMICRIDBASE" : ("algorithmic rid base", SambaParmString, P_GLOBAL, "1000"), + "FORCEDIRECTORYSECURITYMODE": ("force directory security mode", SambaParmString, P_LOCAL, "00"), + "ANNOUNCEVERSION" : ("announce version", SambaParmString, P_GLOBAL, "4.9"), + "USERNAMEMAP" : ("username map", SambaParmString, P_GLOBAL, ""), + "MANGLEDNAMES" : ("mangled names", SambaParmBool, P_LOCAL, "Yes"), + "ROOTDIRECTORY" : ("root directory", SambaParmString, P_GLOBAL, ""), + "DEBUGHIRESTIMESTAMP" : ("debug hires timestamp", SambaParmBool, P_GLOBAL, "No"), + "LOGONDRIVE" : ("logon drive", SambaParmString, P_GLOBAL, ""), + "LOCALMASTER" : ("local master", SambaParmBool, P_GLOBAL, "Yes"), + "ROOTPREEXECCLOSE" : ("root preexec close", SambaParmBool, P_LOCAL, "No"), + "CONFIGFILE" : ("config file", SambaParmString, P_GLOBAL, ""), + "USECLIENTDRIVER" : ("use client driver", SambaParmBool, P_LOCAL, "No"), + "MINPROTOCOL" : ("min protocol", SambaParmString, P_GLOBAL, "CORE"), + "ADDUSERTOGROUPSCRIPT" : ("add user to group script", SambaParmString, P_GLOBAL, ""), + "MAPACLINHERIT" : ("map acl inherit", SambaParmBool, P_LOCAL, "No"), + "DELETEUSERSCRIPT" : ("delete user script", SambaParmString, P_GLOBAL, ""), + "WINBINDUID" : ("idmap uid", SambaParmString, P_GLOBAL, ""), + "READRAW" : ("read raw", SambaParmBool, P_GLOBAL, "Yes"), + "WINBINDENUMGROUPS" : ("winbind enum groups", SambaParmBool, P_GLOBAL, "Yes"), + "PASSWORDLEVEL" : ("password level", SambaParmString, P_GLOBAL, "0"), + "MAXPRINTJOBS" : ("max print jobs", SambaParmString, P_LOCAL, "1000"), + "PRINTCAP" : ("printcap name", SambaParmString, P_GLOBAL, ""), + "LOADPRINTERS" : ("load printers", SambaParmBool, P_GLOBAL, "Yes"), + "DEFAULT" : ("default service", SambaParmString, P_GLOBAL, ""), + "GUESTACCOUNT" : ("guest account", SambaParmString, P_GLOBAL, "nobody"), + "AUTOSERVICES" : ("preload", SambaParmString, P_GLOBAL, ""), + "WRITEABLE" : ("read only", SambaParmBoolRev, P_LOCAL, "Yes"), + "CLIENTLANMANAUTH" : ("client lanman auth", SambaParmBool, P_GLOBAL, "Yes"), + "MESSAGECOMMAND" : ("message command", SambaParmString, P_GLOBAL, ""), + "UNIXEXTENSIONS" : ("unix extensions", SambaParmBool, P_GLOBAL, "Yes"), + "LDAPPASSWORDSYNC" : ("ldap passwd sync", SambaParmString, P_GLOBAL, "no"), + "AFSUSERNAMEMAP" : ("afs username map", SambaParmString, P_GLOBAL, ""), + "SYSLOG" : ("syslog", SambaParmString, P_GLOBAL, "1"), + "SETPRIMARYGROUPSCRIPT" : ("set primary group script", SambaParmString, P_GLOBAL, ""), + "DEADTIME" : ("deadtime", SambaParmString, P_GLOBAL, "0"), + "RESTRICTANONYMOUS" : ("restrict anonymous", SambaParmString, P_GLOBAL, "0"), + "USERNAMELEVEL" : ("username level", SambaParmString, P_GLOBAL, "0"), + "DISPLAYCHARSET" : ("display charset", SambaParmString, P_GLOBAL, "LOCALE"), + "FORCEUSER" : ("force user", SambaParmString, P_LOCAL, ""), + "HOSTSDENY" : ("hosts deny", SambaParmString, P_LOCAL, ""), + "HIDEUNWRITEABLEFILES" : ("hide unwriteable files", SambaParmBool, P_LOCAL, "No"), + "DOSCHARSET" : ("dos charset", SambaParmString, P_GLOBAL, "CP850"), + "DOSFILETIMES" : ("dos filetimes", SambaParmBool, P_LOCAL, "No"), + "REALM" : ("realm", SambaParmString, P_GLOBAL, ""), + "LDAPSUFFIX" : ("ldap suffix", SambaParmString, P_GLOBAL, ""), + "LPPAUSECOMMAND" : ("lppause command", SambaParmString, P_LOCAL, ""), + "FAKEDIRECTORYCREATETIMES": ("fake directory create times", SambaParmBool, P_LOCAL, "No"), + "MAGICSCRIPT" : ("magic script", SambaParmString, P_LOCAL, ""), + "WRITECACHESIZE" : ("write cache size", SambaParmString, P_LOCAL, "0"), + "BLOCKSIZE" : ("block size", SambaParmString, P_LOCAL, "1024"), + "LOCKSPINTIME" : ("lock spin time", SambaParmString, P_GLOBAL, "10"), + "ACLCOMPATIBILITY" : ("acl compatibility", SambaParmString, P_GLOBAL, ""), + "MSDFSPROXY" : ("msdfs proxy", SambaParmString, P_LOCAL, ""), + "POSTEXEC" : ("postexec", SambaParmString, P_LOCAL, ""), + "HIDEUNREADABLE" : ("hide unreadable", SambaParmBool, P_LOCAL, "No"), + "WIDELINKS" : ("wide links", SambaParmBool, P_LOCAL, "Yes"), + "STRICTSYNC" : ("strict sync", SambaParmBool, P_LOCAL, "No"), + "PRINTCAPNAME" : ("printcap name", SambaParmString, P_GLOBAL, ""), + "PREFEREDMASTER" : ("preferred master", SambaParmString, P_GLOBAL, "Auto"), + "MAXMUX" : ("max mux", SambaParmString, P_GLOBAL, "50"), + "VETOOPLOCKFILES" : ("veto oplock files", SambaParmString, P_LOCAL, ""), + "WINBINDSEPARATOR" : ("winbind separator", SambaParmString, P_GLOBAL, "\\"), + "NISHOMEDIR" : ("NIS homedir", SambaParmBool, P_GLOBAL, "No"), + "AVAILABLE" : ("available", SambaParmBool, P_LOCAL, "Yes"), + "KEEPALIVE" : ("keepalive", SambaParmString, P_GLOBAL, "300"), + "USERNAME" : ("username", SambaParmString, P_LOCAL, ""), + "PRINTCOMMAND" : ("print command", SambaParmString, P_LOCAL, ""), + "LPRESUMECOMMAND" : ("lpresume command", SambaParmString, P_LOCAL, ""), + "USEKERBEROSKEYTAB" : ("use kerberos keytab", SambaParmBool, P_GLOBAL, "No"), + "HOSTSALLOW" : ("hosts allow", SambaParmString, P_LOCAL, ""), + "MAXOPENFILES" : ("max open files", SambaParmString, P_GLOBAL, "10000"), + "PARANOIDSERVERSECURITY" : ("paranoid server security", SambaParmBool, P_GLOBAL, "Yes"), + "WTMPDIRECTORY" : ("wtmp directory", SambaParmString, P_GLOBAL, ""), + "ADDPRINTERCOMMAND" : ("addprinter command", SambaParmString, P_GLOBAL, ""), + "PRINTERADMIN" : ("printer admin", SambaParmString, P_LOCAL, ""), + "WINSSERVER" : ("wins server", SambaParmString, P_GLOBAL, ""), + "LDAPTIMEOUT" : ("ldap timeout", SambaParmString, P_GLOBAL, "15"), + "LOCKDIRECTORY" : ("lock directory", SambaParmString, P_GLOBAL, "/var/lib/samba"), + "LOGONHOME" : ("logon home", SambaParmString, P_GLOBAL, "\\%N\%U"), + "MINPASSWDLENGTH" : ("min password length", SambaParmString, P_GLOBAL, "5"), + "CLIENTPLAINTEXTAUTH" : ("client plaintext auth", SambaParmBool, P_GLOBAL, "Yes"), + "CSCPOLICY" : ("csc policy", SambaParmString, P_LOCAL, "manual"), + "ADDSHARECOMMAND" : ("add share command", SambaParmString, P_GLOBAL, ""), + "MANGLINGCHAR" : ("mangling char", SambaParmString, P_LOCAL, "~"), + "DIRECTORY" : ("path", SambaParmString, P_LOCAL, ""), + "DEBUGTIMESTAMP" : ("debug timestamp", SambaParmBool, P_GLOBAL, "Yes"), + "ALLOWHOSTS" : ("hosts allow", SambaParmString, P_LOCAL, ""), + "FSTYPE" : ("fstype", SambaParmString, P_LOCAL, "NTFS"), + "BLOCKINGLOCKS" : ("blocking locks", SambaParmBool, P_LOCAL, "Yes"), + "LDAPSSL" : ("ldap ssl", SambaParmString, P_GLOBAL, ""), + "PAMPASSWORDCHANGE" : ("pam password change", SambaParmBool, P_GLOBAL, "No"), + "GUESTOK" : ("guest ok", SambaParmBool, P_LOCAL, "No"), + "DEFAULTDEVMODE" : ("default devmode", SambaParmBool, P_LOCAL, "No"), + "MAXDISKSIZE" : ("max disk size", SambaParmString, P_GLOBAL, "0"), + "ADDMACHINESCRIPT" : ("add machine script", SambaParmString, P_GLOBAL, ""), + "MANGLEPREFIX" : ("mangle prefix", SambaParmString, P_GLOBAL, "1"), + "DISABLENETBIOS" : ("disable netbios", SambaParmBool, P_GLOBAL, "No"), + "LOGONPATH" : ("logon path", SambaParmString, P_GLOBAL, "\\%N\%U\profile"), + "IDMAPBACKEND" : ("idmap backend", SambaParmString, P_GLOBAL, ""), + "SHORTPRESERVECASE" : ("short preserve case", SambaParmBool, P_LOCAL, "Yes"), + "CUPSSERVER" : ("cups server", SambaParmString, P_GLOBAL, ""), + "NTPIPESUPPORT" : ("nt pipe support", SambaParmBool, P_GLOBAL, "Yes"), + "READONLY" : ("read only", SambaParmBool, P_LOCAL, "Yes"), + "MACHINEPASSWORDTIMEOUT" : ("machine password timeout", SambaParmString, P_GLOBAL, "604800"), + "PIDDIRECTORY" : ("pid directory", SambaParmString, P_GLOBAL, "/var/run"), + "PUBLIC" : ("guest ok", SambaParmBool, P_LOCAL, "No"), + "DEBUGPID" : ("debug pid", SambaParmBool, P_GLOBAL, "No"), + "GUESTONLY" : ("guest only", SambaParmBool, P_LOCAL, "No"), + "DELETEGROUPSCRIPT" : ("delete group script", SambaParmString, P_GLOBAL, ""), + "CUPSOPTIONS" : ("cups options", SambaParmString, P_LOCAL, ""), + "PASSWDCHAT" : ("passwd chat", SambaParmString, P_GLOBAL, "*new*password* %n\n *new*password* %n\n *changed*"), + "STRICTLOCKING" : ("strict locking", SambaParmString, P_LOCAL, "Yes"), + "TEMPLATEHOMEDIR" : ("template homedir", SambaParmString, P_GLOBAL, "/home/%D/%U"), + "WINBINDGID" : ("idmap gid", SambaParmString, P_GLOBAL, ""), + "INHERITPERMISSIONS" : ("inherit permissions", SambaParmBool, P_LOCAL, "No"), + "TIMESERVER" : ("time server", SambaParmBool, P_GLOBAL, "No"), + "BROWSELIST" : ("browse list", SambaParmBool, P_GLOBAL, "Yes"), + "HOSTNAMELOOKUPS" : ("hostname lookups", SambaParmBool, P_GLOBAL, "No"), + "DOSFILETIMERESOLUTION" : ("dos filetime resolution", SambaParmBool, P_LOCAL, "No"), + "CREATEMASK" : ("create mask", SambaParmString, P_LOCAL, "0744"), + "WINSHOOK" : ("wins hook", SambaParmString, P_GLOBAL, ""), + "DEFAULTCASE" : ("default case", SambaParmString, P_LOCAL, "lower"), + "PATH" : ("path", SambaParmString, P_LOCAL, ""), + "SHOWADDPRINTERWIZARD" : ("show add printer wizard", SambaParmBool, P_GLOBAL, "Yes"), + "WINSPARTNERS" : ("wins partners", SambaParmString, P_GLOBAL, ""), + "ENABLEPRIVILEGES" : ("enable privileges", SambaParmBool, P_GLOBAL, "No"), + "VFSOBJECTS" : ("vfs objects", SambaParmString, P_LOCAL, ""), + "STRICTALLOCATE" : ("strict allocate", SambaParmBool, P_LOCAL, "No"), + "PREEXEC" : ("preexec", SambaParmString, P_LOCAL, ""), + "WINSSUPPORT" : ("wins support", SambaParmBool, P_GLOBAL, "No"), + "HOSTMSDFS" : ("host msdfs", SambaParmBool, P_GLOBAL, "No"), + "AFSTOKENLIFETIME" : ("afs token lifetime", SambaParmString, P_GLOBAL, "604800"), + "PRINTOK" : ("printable", SambaParmBool, P_LOCAL, "No"), + "TEMPLATEPRIMARYGROUP" : ("template primary group", SambaParmString, P_GLOBAL, "nobody"), + "PASSWDPROGRAM" : ("passwd program", SambaParmString, P_GLOBAL, ""), + "SYNCALWAYS" : ("sync always", SambaParmBool, P_LOCAL, "No"), + "QUEUEPAUSECOMMAND" : ("queuepause command", SambaParmString, P_LOCAL, ""), + "BINDINTERFACESONLY" : ("bind interfaces only", SambaParmBool, P_GLOBAL, "No"), + "MAXWINSTTL" : ("max wins ttl", SambaParmString, P_GLOBAL, "518400"), + "GETWDCACHE" : ("getwd cache", SambaParmBool, P_GLOBAL, "Yes"), + "MAGICOUTPUT" : ("magic output", SambaParmString, P_LOCAL, ""), + "ADMINUSERS" : ("admin users", SambaParmString, P_LOCAL, ""), + "DIRECTORYMODE" : ("directory mask", SambaParmString, P_LOCAL, "0755"), + "CLIENTSIGNING" : ("client signing", SambaParmString, P_GLOBAL, "auto"), + "PASSDBBACKEND" : ("passdb backend", SambaParmString, P_GLOBAL, "smbpasswd"), + "CASESIGNAMES" : ("case sensitive", SambaParmString, P_LOCAL, "Auto"), + "SETQUOTACOMMAND" : ("set quota command", SambaParmString, P_GLOBAL, ""), + "LPQCOMMAND" : ("lpq command", SambaParmString, P_LOCAL, ""), + "SERVERSTRING" : ("server string", SambaParmString, P_GLOBAL, "Samba 3.0.11pre2-SVN-build-4840"), + "DEFAULTSERVICE" : ("default service", SambaParmString, P_GLOBAL, ""), + "WINBINDUSEDEFAULTDOMAIN": ("winbind use default domain", SambaParmBool, P_GLOBAL, "No"), + "INTERFACES" : ("interfaces", SambaParmString, P_GLOBAL, ""), + "ROOTDIR" : ("root directory", SambaParmString, P_GLOBAL, ""), + "ADDUSERSCRIPT" : ("add user script", SambaParmString, P_GLOBAL, ""), + "CLIENTNTLMV2AUTH" : ("client NTLMv2 auth", SambaParmBool, P_GLOBAL, "No"), + "FORCEUNKNOWNACLUSER" : ("force unknown acl user", SambaParmBool, P_LOCAL, "No"), + "MANGLEDMAP" : ("mangled map", SambaParmString, P_LOCAL, ""), + "NTLMAUTH" : ("ntlm auth", SambaParmBool, P_GLOBAL, "Yes"), + "INHERITACLS" : ("inherit acls", SambaParmBool, P_LOCAL, "No"), + "HOSTSEQUIV" : ("hosts equiv", SambaParmString, P_GLOBAL, ""), + "ALLOWTRUSTEDDOMAINS" : ("allow trusted domains", SambaParmBool, P_GLOBAL, "Yes"), + "MINPASSWORDLENGTH" : ("min password length", SambaParmString, P_GLOBAL, "5"), + "USERS" : ("username", SambaParmString, P_LOCAL, ""), + "PRELOAD" : ("preload", SambaParmString, P_GLOBAL, ""), + "DEBUGUID" : ("debug uid", SambaParmBool, P_GLOBAL, "No"), + "CHANGESHARECOMMAND" : ("change share command", SambaParmString, P_GLOBAL, ""), + "BROWSABLE" : ("browseable", SambaParmBool, P_LOCAL, "Yes"), + "ENHANCEDBROWSING" : ("enhanced browsing", SambaParmBool, P_GLOBAL, "Yes"), + "PANICACTION" : ("panic action", SambaParmString, P_GLOBAL, ""), + "LDAPMACHINESUFFIX" : ("ldap machine suffix", SambaParmString, P_GLOBAL, ""), + "UPDATEENCRYPTED" : ("update encrypted", SambaParmBool, P_GLOBAL, "No"), + "MAXTTL" : ("max ttl", SambaParmString, P_GLOBAL, "259200"), + "WRITABLE" : ("read only", SambaParmBoolRev, P_LOCAL, "Yes"), + "SHAREMODES" : ("share modes", SambaParmBool, P_LOCAL, "Yes"), + "REMOTEBROWSESYNC" : ("remote browse sync", SambaParmString, P_GLOBAL, ""), + "STOREDOSATTRIBUTES" : ("store dos attributes", SambaParmBool, P_LOCAL, "No"), + "CLIENTSCHANNEL" : ("client schannel", SambaParmString, P_GLOBAL, "Auto"), + "WRITELIST" : ("write list", SambaParmString, P_LOCAL, ""), + "ADDGROUPSCRIPT" : ("add group script", SambaParmString, P_GLOBAL, ""), + "OPLOCKBREAKWAITTIME" : ("oplock break wait time", SambaParmString, P_GLOBAL, "0"), + "TIMEOFFSET" : ("time offset", SambaParmString, P_GLOBAL, "0"), + "LDAPDELETEDN" : ("ldap delete dn", SambaParmBool, P_GLOBAL, "No"), + "AFSSHARE" : ("afs share", SambaParmBool, P_LOCAL, "No"), + "ROOT" : ("root directory", SambaParmString, P_GLOBAL, ""), + "NAMERESOLVEORDER" : ("name resolve order", SambaParmString, P_GLOBAL, "lmhosts wins host bcast"), +} +##### end of smbparm.y ########################################## +################################################################# diff --git a/examples/scripts/users_and_groups/adduserstogroups.pl b/examples/scripts/users_and_groups/adduserstogroups.pl new file mode 100755 index 0000000000..6759428774 --- /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: madatory 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 0000000000..60f34b84f2 --- /dev/null +++ b/examples/scripts/users_and_groups/createdomobj.pl @@ -0,0 +1,157 @@ +#!/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 = $target_type; # 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: madatory 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}; +} + +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/wins_hook/README b/examples/scripts/wins_hook/README new file mode 100644 index 0000000000..1147f57e22 --- /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 0000000000..a4c1a79ab9 --- /dev/null +++ b/examples/scripts/wins_hook/dns_update @@ -0,0 +1,94 @@ +#!/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 +# readding 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 diff --git a/examples/smb.conf.default b/examples/smb.conf.default new file mode 100644 index 0000000000..971ca19c83 --- /dev/null +++ b/examples/smb.conf.default @@ -0,0 +1,271 @@ +# This is the main Samba configuration file. You should read the +# smb.conf(5) manual page in order to understand the options listed +# here. Samba has a huge number of configurable options (perhaps too +# many!) most of which are not shown in this example +# +# For a step to step guide on installing, configuring and using samba, +# read the Samba-HOWTO-Collection. This may be obtained from: +# http://www.samba.org/samba/docs/Samba-HOWTO-Collection.pdf +# +# Many working examples of smb.conf files can be found in the +# Samba-Guide which is generated daily and can be downloaded from: +# http://www.samba.org/samba/docs/Samba-Guide.pdf +# +# Any line which starts with a ; (semi-colon) or a # (hash) +# is a comment and is ignored. In this example we will use a # +# for commentry and a ; for parts of the config file that you +# may wish to enable +# +# NOTE: Whenever you modify this file you should run the command "testparm" +# to check that you have not made any basic syntactic errors. +# +#======================= Global Settings ===================================== +[global] + +# workgroup = NT-Domain-Name or Workgroup-Name, eg: MIDEARTH + workgroup = MYGROUP + +# server string is the equivalent of the NT Description field + server string = Samba Server + +# Security mode. Defines in which mode Samba will operate. Possible +# values are share, user, server, domain and ads. Most people will want +# user level security. See the Samba-HOWTO-Collection for details. + security = user + +# This option is important for security. It allows you to restrict +# connections to machines which are on your local network. The +# following example restricts access to two C class networks and +# the "loopback" interface. For more examples of the syntax see +# the smb.conf man page +; hosts allow = 192.168.1. 192.168.2. 127. + +# If you want to automatically load your printer list rather +# than setting them up individually then you'll need this + load printers = yes + +# you may wish to override the location of the printcap file +; printcap name = /etc/printcap + +# on SystemV system setting printcap name to lpstat should allow +# you to automatically obtain a printer list from the SystemV spool +# system +; printcap name = lpstat + +# It should not be necessary to specify the print system type unless +# it is non-standard. Currently supported print systems include: +# bsd, cups, sysv, plp, lprng, aix, hpux, qnx +; printing = cups + +# Uncomment this if you want a guest account, you must add this to /etc/passwd +# otherwise the user "nobody" is used +; guest account = pcguest + +# this tells Samba to use a separate log file for each machine +# that connects + log file = /usr/local/samba/var/log.%m + +# Put a capping on the size of the log files (in Kb). + max log size = 50 + +# Use password server option only with security = server +# The argument list may include: +# password server = My_PDC_Name [My_BDC_Name] [My_Next_BDC_Name] +# or to auto-locate the domain controller/s +# password server = * +; password server = <NT-Server-Name> + +# Use the realm option only with security = ads +# Specifies the Active Directory realm the host is part of +; realm = MY_REALM + +# Backend to store user information in. New installations should +# use either tdbsam or ldapsam. smbpasswd is available for backwards +# compatibility. tdbsam requires no further configuration. +; passdb backend = tdbsam + +# Using the following line enables you to customise your configuration +# on a per machine basis. The %m gets replaced with the netbios name +# of the machine that is connecting. +# Note: Consider carefully the location in the configuration file of +# this line. The included file is read at that point. +; include = /usr/local/samba/lib/smb.conf.%m + +# Configure Samba to use multiple interfaces +# If you have multiple network interfaces then you must list them +# here. See the man page for details. +; interfaces = 192.168.12.2/24 192.168.13.2/24 + +# Browser Control Options: +# set local master to no if you don't want Samba to become a master +# browser on your network. Otherwise the normal election rules apply +; local master = no + +# OS Level determines the precedence of this server in master browser +# elections. The default value should be reasonable +; os level = 33 + +# Domain Master specifies Samba to be the Domain Master Browser. This +# allows Samba to collate browse lists between subnets. Don't use this +# if you already have a Windows NT domain controller doing this job +; domain master = yes + +# Preferred Master causes Samba to force a local browser election on startup +# and gives it a slightly higher chance of winning the election +; preferred master = yes + +# Enable this if you want Samba to be a domain logon server for +# Windows95 workstations. +; domain logons = yes + +# if you enable domain logons then you may want a per-machine or +# per user logon script +# run a specific logon batch file per workstation (machine) +; logon script = %m.bat +# run a specific logon batch file per username +; logon script = %U.bat + +# Where to store roving profiles (only for Win95 and WinNT) +# %L substitutes for this servers netbios name, %U is username +# You must uncomment the [Profiles] share below +; logon path = \\%L\Profiles\%U + +# Windows Internet Name Serving Support Section: +# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server +; wins support = yes + +# WINS Server - Tells the NMBD components of Samba to be a WINS Client +# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both +; wins server = w.x.y.z + +# WINS Proxy - Tells Samba to answer name resolution queries on +# behalf of a non WINS capable client, for this to work there must be +# at least one WINS Server on the network. The default is NO. +; wins proxy = yes + +# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names +# via DNS nslookups. The default is NO. + dns proxy = no + +# These scripts are used on a domain controller or stand-alone +# machine to add or delete corresponding unix accounts +; add user script = /usr/sbin/useradd %u +; add group script = /usr/sbin/groupadd %g +; add machine script = /usr/sbin/adduser -n -g machines -c Machine -d /dev/null -s /bin/false %u +; delete user script = /usr/sbin/userdel %u +; delete user from group script = /usr/sbin/deluser %u %g +; delete group script = /usr/sbin/groupdel %g + + +#============================ Share Definitions ============================== +[homes] + comment = Home Directories + browseable = no + writable = yes + +# Un-comment the following and create the netlogon directory for Domain Logons +; [netlogon] +; comment = Network Logon Service +; path = /usr/local/samba/lib/netlogon +; guest ok = yes +; writable = no +; share modes = no + + +# Un-comment the following to provide a specific roving profile share +# the default is to use the user's home directory +;[Profiles] +; path = /usr/local/samba/profiles +; browseable = no +; guest ok = yes + + +# NOTE: If you have a BSD-style print system there is no need to +# specifically define each individual printer +[printers] + comment = All Printers + path = /usr/spool/samba + browseable = no +# Set public = yes to allow user 'guest account' to print + guest ok = no + writable = no + printable = yes + +# This one is useful for people to share files +;[tmp] +; comment = Temporary file space +; path = /tmp +; read only = no +; public = yes + +# A publicly accessible directory, but read only, except for people in +# the "staff" group +;[public] +; comment = Public Stuff +; path = /home/samba +; public = yes +; writable = yes +; printable = no +; write list = @staff + +# Other examples. +# +# A private printer, usable only by fred. Spool data will be placed in fred's +# home directory. Note that fred must have write access to the spool directory, +# wherever it is. +;[fredsprn] +; comment = Fred's Printer +; valid users = fred +; path = /homes/fred +; printer = freds_printer +; public = no +; writable = no +; printable = yes + +# A private directory, usable only by fred. Note that fred requires write +# access to the directory. +;[fredsdir] +; comment = Fred's Service +; path = /usr/somewhere/private +; valid users = fred +; public = no +; writable = yes +; printable = no + +# a service which has a different directory for each machine that connects +# this allows you to tailor configurations to incoming machines. You could +# also use the %U option to tailor it by user name. +# The %m gets replaced with the machine name that is connecting. +;[pchome] +; comment = PC Directories +; path = /usr/pc/%m +; public = no +; writable = yes + +# A publicly accessible directory, read/write to all users. Note that all files +# created in the directory by users will be owned by the default user, so +# any user with access can delete any other user's files. Obviously this +# directory must be writable by the default user. Another user could of course +# be specified, in which case all files would be owned by that user instead. +;[public] +; path = /usr/somewhere/else/public +; public = yes +; only guest = yes +; writable = yes +; printable = no + +# The following two entries demonstrate how to share a directory so that two +# users can place files there that will be owned by the specific users. In this +# setup, the directory should be writable by both users and should have the +# sticky bit set on it to prevent abuse. Obviously this could be extended to +# as many users as required. +;[myshare] +; comment = Mary's and Fred's stuff +; path = /usr/somewhere/shared +; valid users = mary fred +; public = no +; writable = yes +; printable = no +; create mask = 0765 + + diff --git a/examples/tridge/README b/examples/tridge/README new file mode 100644 index 0000000000..11c72f20b3 --- /dev/null +++ b/examples/tridge/README @@ -0,0 +1,8 @@ +This is the configuration I use at home. I have 2 client PCs, one +running Win95, one running alternately WfWg and NTAS3.5. My server is +a 486dx2-66 Linux box. + +Note that I use the %a and %m macros to load smb.conf extensions +particular to machines and architectures. This gives me a lot of +flexibility in how I handle each of the machines. + diff --git a/examples/tridge/smb.conf b/examples/tridge/smb.conf new file mode 100644 index 0000000000..a2f269f3b7 --- /dev/null +++ b/examples/tridge/smb.conf @@ -0,0 +1,101 @@ +[global] + config file = /usr/local/samba/smb.conf.%m + status = yes + security = user + encrypt passwords = yes + server string = Tridge (%v,%h) + load printers = yes + log level = 1 + log file = /usr/local/samba/var/log.%m + guest account = pcguest + hosts allow = 192.0.2. localhost + password level = 2 + auto services = tridge susan + message command = csh -c '/usr/bin/X11/xedit -display :0 %s;rm %s' & + read prediction = yes + socket options = TCP_NODELAY + valid chars = : : : + share modes = yes + locking = yes + strict locking = yes + keepalive = 30 + include = /usr/local/samba/lib/smb.conf.%m + include = /usr/local/samba/lib/smb.conf.%a + + +[uniprint] + comment = University Printing + path = /home/susan/print + user = susan + postscript = yes + print ok = yes + print command = xmenu -heading "%s" OK& + +[testprn] + comment = Test printer + path = /tmp + user = susan + print ok = yes + print command = cp %s /tmp/smb.%U.prn + lpq command = cat /tmp/xxyz + +[amd] + comment = amd area + path = /mount + force user = tridge + read only = no + +[homes] + browseable = no + guest ok = no + read only = no + create mask = 0755 + +[printers] + browseable = no + comment = Printer in Printcap + guest ok = no + path = /tmp + read only = no + print ok = yes + +[dos] + browseable = yes + comment = Dos Files + force group = samba + create mode = 0775 + path = /home/tridge/dos + copy = homes + +[msoffice] + browseable = yes + comment = Microsoft Office + force group = samba + create mode = 0775 + path = /data/msoffice + read only = yes + +[root] + comment = Root Dir + copy = dos + path = / + dont descend = /proc ./proc /etc + +[tmp] + comment = tmp files + copy = dos + path = /tmp + read only = no + + +[cdrom] + comment = Tridge's CdRom + path = /mount/cdrom + read only = yes + locking = no + +[data] + comment = Data Partition + path = /data + read only = yes + guest ok = yes diff --git a/examples/tridge/smb.conf.WinNT b/examples/tridge/smb.conf.WinNT new file mode 100644 index 0000000000..f490f830ca --- /dev/null +++ b/examples/tridge/smb.conf.WinNT @@ -0,0 +1,14 @@ +#log level = 4 +#readraw = no +#writeraw = no + + + + + + + + + + + diff --git a/examples/tridge/smb.conf.fjall b/examples/tridge/smb.conf.fjall new file mode 100644 index 0000000000..76f4d0e3ca --- /dev/null +++ b/examples/tridge/smb.conf.fjall @@ -0,0 +1,21 @@ +;log level = 4 +;readraw = no +;writeraw = no +;password level = 4 +;mangled map = (;1 ) +;protocol = lanman1 +;user = susan +;getwd cache = no + + + + + + + + + + + + + diff --git a/examples/tridge/smb.conf.lapland b/examples/tridge/smb.conf.lapland new file mode 100644 index 0000000000..f490f830ca --- /dev/null +++ b/examples/tridge/smb.conf.lapland @@ -0,0 +1,14 @@ +#log level = 4 +#readraw = no +#writeraw = no + + + + + + + + + + + diff --git a/examples/tridge/smb.conf.vittjokk b/examples/tridge/smb.conf.vittjokk new file mode 100644 index 0000000000..919ecd1542 --- /dev/null +++ b/examples/tridge/smb.conf.vittjokk @@ -0,0 +1,14 @@ +;protocol = LANMAN2 +log level = 2 + + + + + + + + + + + + diff --git a/examples/validchars/msdos70.out b/examples/validchars/msdos70.out new file mode 100644 index 0000000000..a722b83604 --- /dev/null +++ b/examples/validchars/msdos70.out @@ -0,0 +1,257 @@ +255: ok
+254: ok
+253: ok
+252: ok
+251: ok
+250: ok
+249: ok
+248: ok
+247: ok
+246: ok
+245: ok
+244: ok
+243: ok
+242: ok
+241: ok
+240: ok
+239: ok
+238: ok
+237: ok
+236: 237
+235: ok
+234: ok
+233: ok
+232: ok
+231: 232
+230: ok
+229: ok
+228: 229
+227: ok
+226: ok
+225: ok
+224: ok
+223: ok
+222: ok
+221: ok
+220: ok
+219: ok
+218: ok
+217: ok
+216: ok
+215: ok
+214: ok
+213: 73
+212: ok
+211: ok
+210: ok
+209: ok
+208: 209
+207: ok
+206: ok
+205: ok
+204: ok
+203: ok
+202: ok
+201: ok
+200: ok
+199: ok
+198: 199
+197: ok
+196: ok
+195: ok
+194: ok
+193: ok
+192: ok
+191: ok
+190: ok
+189: ok
+188: ok
+187: ok
+186: ok
+185: ok
+184: ok
+183: ok
+182: ok
+181: ok
+180: ok
+179: ok
+178: ok
+177: ok
+176: ok
+175: ok
+174: ok
+173: ok
+172: ok
+171: ok
+170: ok
+169: ok
+168: ok
+167: ok
+166: ok
+165: ok
+164: 165
+163: 233
+162: 224
+161: 214
+160: 181
+159: ok
+158: ok
+157: ok
+156: ok
+155: 157
+154: ok
+153: ok
+152: length 0
+151: 235
+150: 234
+149: 227
+148: 153
+147: 226
+146: ok
+145: 146
+144: ok
+143: ok
+142: ok
+141: 222
+140: 215
+139: 216
+138: 212
+137: 211
+136: 210
+135: 128
+134: 143
+133: 183
+132: 142
+131: 182
+130: 144
+129: 154
+128: ok
+127: ok
+126: ok
+125: ok
+124: open unlink 0
+123: ok
+122: 90
+121: 89
+120: 88
+119: 87
+118: 86
+117: 85
+116: 84
+115: 83
+114: 82
+113: 81
+112: 80
+111: 79
+110: 78
+109: 77
+108: 76
+107: 75
+106: 74
+105: 73
+104: 72
+103: 71
+102: 70
+101: 69
+100: 68
+99: 67
+98: 66
+97: 65
+96: ok
+95: ok
+94: ok
+93: open unlink 0
+92: open unlink 0
+91: open unlink 0
+90: ok
+89: ok
+88: ok
+87: ok
+86: ok
+85: ok
+84: ok
+83: ok
+82: ok
+81: ok
+80: ok
+79: ok
+78: ok
+77: ok
+76: ok
+75: ok
+74: ok
+73: ok
+72: ok
+71: ok
+70: ok
+69: ok
+68: ok
+67: ok
+66: ok
+65: ok
+64: ok
+63: open unlink 0
+62: open unlink 0
+61: open unlink 0
+60: open unlink 0
+59: open unlink 0
+58: open unlink 0
+57: ok
+56: ok
+55: ok
+54: ok
+53: ok
+52: ok
+51: ok
+50: ok
+49: ok
+48: ok
+47: open unlink 0
+46: open unlink 0
+45: ok
+44: open unlink 0
+43: open unlink 0
+42: open unlink 0
+41: ok
+40: ok
+39: ok
+38: ok
+37: ok
+36: ok
+35: ok
+34: open unlink 0
+33: ok
+32: open unlink 0
+31: open unlink 0
+30: open unlink 0
+29: open unlink 0
+28: open unlink 0
+27: open unlink 0
+26: open unlink 0
+25: open unlink 0
+24: open unlink 0
+23: open unlink 0
+22: open unlink 0
+21: open unlink 0
+20: open unlink 0
+19: open unlink 0
+18: open unlink 0
+17: open unlink 0
+16: open unlink 0
+15: open unlink 0
+14: open unlink 0
+13: open unlink 0
+12: open unlink 0
+11: open unlink 0
+10: open unlink 0
+9: open unlink 0
+8: open unlink 0
+7: open unlink 0
+6: open unlink 0
+5: open unlink 0
+4: open unlink 0
+3: open unlink 0
+2: open unlink 0
+1: open unlink 0
+
+ valid chars = 73:213 213:73 73:73 33 35 36 37 38 39 40 41 45 48 49 50 51 52 53 54 55 56 57 64 97:65 98:66 99:67 100:68 101:69 102:70 103:71 104:72 105:73 106:74 107:75 108:76 109:77 110:78 111:79 112:80 113:81 114:82 115:83 116:84 117:85 118:86 119:87 120:88 121:89 122:90 94 95 96 123 125 126 127 135:128 132:142 134:143 130:144 145:146 148:153 129:154 156 155:157 158 159 164:165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 160:181 131:182 133:183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198:199 200 201 202 203 204 205 206 207 208:209 136:210 137:211 138:212 161:214 140:215 139:216 217 218 219 220 221 141:222 223 162:224 225 147:226 149:227 228:229 230 231:232 163:233 150:234 151:235 236:237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
diff --git a/examples/validchars/nwdos70.out b/examples/validchars/nwdos70.out new file mode 100644 index 0000000000..b0dbf62853 --- /dev/null +++ b/examples/validchars/nwdos70.out @@ -0,0 +1,257 @@ +255: ok
+254: ok
+253: ok
+252: ok
+251: ok
+250: ok
+249: ok
+248: ok
+247: ok
+246: ok
+245: ok
+244: ok
+243: ok
+242: ok
+241: ok
+240: ok
+239: ok
+238: ok
+237: ok
+236: ok
+235: ok
+234: ok
+233: ok
+232: ok
+231: ok
+230: ok
+229: ok
+228: ok
+227: ok
+226: ok
+225: ok
+224: ok
+223: ok
+222: ok
+221: ok
+220: ok
+219: ok
+218: ok
+217: ok
+216: ok
+215: ok
+214: ok
+213: ok
+212: ok
+211: ok
+210: ok
+209: ok
+208: ok
+207: ok
+206: ok
+205: ok
+204: ok
+203: ok
+202: ok
+201: ok
+200: ok
+199: ok
+198: ok
+197: ok
+196: ok
+195: ok
+194: ok
+193: ok
+192: ok
+191: ok
+190: ok
+189: ok
+188: ok
+187: ok
+186: ok
+185: ok
+184: ok
+183: ok
+182: ok
+181: ok
+180: ok
+179: ok
+178: ok
+177: ok
+176: ok
+175: ok
+174: ok
+173: ok
+172: ok
+171: ok
+170: ok
+169: ok
+168: ok
+167: ok
+166: ok
+165: ok
+164: 165
+163: 85
+162: 79
+161: 73
+160: 65
+159: ok
+158: ok
+157: ok
+156: ok
+155: ok
+154: ok
+153: ok
+152: 89
+151: 85
+150: 85
+149: 79
+148: 153
+147: 79
+146: ok
+145: 146
+144: ok
+143: ok
+142: ok
+141: 73
+140: 73
+139: 73
+138: 69
+137: 69
+136: 69
+135: 128
+134: 143
+133: 65
+132: 142
+131: 65
+130: 69
+129: 154
+128: ok
+127: ok
+126: ok
+125: ok
+124: open unlink 0
+123: ok
+122: 90
+121: 89
+120: 88
+119: 87
+118: 86
+117: 85
+116: 84
+115: 83
+114: 82
+113: 81
+112: 80
+111: 79
+110: 78
+109: 77
+108: 76
+107: 75
+106: 74
+105: 73
+104: 72
+103: 71
+102: 70
+101: 69
+100: 68
+99: 67
+98: 66
+97: 65
+96: ok
+95: ok
+94: ok
+93: open unlink 0
+92: open unlink 0
+91: open unlink 0
+90: ok
+89: ok
+88: ok
+87: ok
+86: ok
+85: ok
+84: ok
+83: ok
+82: ok
+81: ok
+80: ok
+79: ok
+78: ok
+77: ok
+76: ok
+75: ok
+74: ok
+73: ok
+72: ok
+71: ok
+70: ok
+69: ok
+68: ok
+67: ok
+66: ok
+65: ok
+64: ok
+63: open unlink 0
+62: open unlink 0
+61: open unlink 0
+60: open unlink 0
+59: open unlink 0
+58: open unlink 0
+57: ok
+56: ok
+55: ok
+54: ok
+53: ok
+52: ok
+51: ok
+50: ok
+49: ok
+48: ok
+47: open unlink 0
+46: open unlink 0
+45: ok
+44: open unlink 0
+43: open unlink 0
+42: open unlink 0
+41: ok
+40: ok
+39: ok
+38: ok
+37: ok
+36: ok
+35: ok
+34: open unlink 0
+33: ok
+32: length 0
+31: open unlink 0
+30: open unlink 0
+29: open unlink 0
+28: open unlink 0
+27: open unlink 0
+26: open unlink 0
+25: open unlink 0
+24: open unlink 0
+23: open unlink 0
+22: open unlink 0
+21: open unlink 0
+20: open unlink 0
+19: open unlink 0
+18: open unlink 0
+17: open unlink 0
+16: open unlink 0
+15: open unlink 0
+14: open unlink 0
+13: open unlink 0
+12: open unlink 0
+11: open unlink 0
+10: open unlink 0
+9: open unlink 0
+8: open unlink 0
+7: open unlink 0
+6: open unlink 0
+5: open unlink 0
+4: open unlink 0
+3: open unlink 0
+2: open unlink 0
+1: open unlink 0
+
+ valid chars = 69:130 130:69 69:69 65:131 131:65 65:65 65:133 133:65 65:65 69:136 136:69 69:69 69:137 137:69 69:69 69:138 138:69 69:69 73:139 139:73 73:73 73:140 140:73 73:73 73:141 141:73 73:73 79:147 147:79 79:79 79:149 149:79 79:79 85:150 150:85 85:85 85:151 151:85 85:85 89:152 152:89 89:89 65:160 160:65 65:65 73:161 161:73 73:73 79:162 162:79 79:79 85:163 163:85 85:85 33 35 36 37 38 39 40 41 45 48 49 50 51 52 53 54 55 56 57 64 97:65 98:66 99:67 100:68 101:69 102:70 103:71 104:72 105:73 106:74 107:75 108:76 109:77 110:78 111:79 112:80 113:81 114:82 115:83 116:84 117:85 118:86 119:87 120:88 121:89 122:90 94 95 96 123 125 126 127 135:128 132:142 134:143 144 145:146 148:153 129:154 155 156 157 158 159 164:165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
diff --git a/examples/validchars/readme b/examples/validchars/readme new file mode 100644 index 0000000000..6487fbd766 --- /dev/null +++ b/examples/validchars/readme @@ -0,0 +1,101 @@ +Note: All files in this directory are DOS formatted (CRLF line terminator).
+
+!!! VIRUS WARNING !!! I do not know if VALIDCHR.COM is virus free !!!
+I think that my system is virus free here because I do not run any games
+or other copied software. I only run Shareware/Freeware etc. from CD-ROMs
+or from registered disks, however I do not use viral scanners because
+I have not registered any (I consider `having no sex' is better than
+`testing for AIDS on a regular basis', if you know what I mean).
+
+This is VALIDCHR, a little DOS program I wrote to create
+an apropriate `valid chars =' config parameter.
+It is freeware and is thought to be distributed freely with Samba.
+
+WARNING:
+ Your SMB driver may use another character map as the one VALIDCHR
+ sees. The only way you can tell this is that some file names fail.
+ Under Win95 everything is fine, though.
+
+Usage:
+ c:
+ mkdir junk_dir
+ cd junk_dir
+ a:validchr > a:output.log
+ cd ..
+ rmdir junk_dir
+
+Siedeffects:
+ Files named *.TST may be deleted.
+
+Verification:
+ For diagnostic purpose you can run VALIDCHR on a Samba mounted drive.
+ Then you can use unix diff to compare the output of the network and
+ the hard drive. These two outputs usually differ! However there
+ should be few differences. I get following on Win95 (c: visa e:)
+ 104c104
+ < 152: length 0
+ ---
+ > 152: 95
+ (diff line for `valid chars =' deleted because it's uninteresting)
+ You can see, `y diaresis' can be mapped on the network drive while
+ it cannot be mapped on the hard drive. Everything else is identical.
+ However this gives a hint that one can improve the mapping.
+
+Bugs:
+ Yes, probably some.
+
+
+VALIDCHR must be run on the system which character mapping should be probed.
+It must be run on the hard drive for this. VALIDCHR ALTERS THE CURRENT
+DIRECTORY AND REMOVES SOME FILES, SO ALWAYS RUN IT IN A junk DIRECTORY !!!
+You should redirect the output of VALIDCHR. At the end of the output is a
+line like
+ valid chars = x:y y:x x:x ... a:b c ...
+which is suitable for your smb.conf file. (you should remove the DOS CR
+character, because DOS uses CRLF while Unix uses LF only.)
+
+Note that some mappings at the beginning of the `valid chars =' line like
+A:B B:A B:B
+might look a little bit strange to you, however sometimes character A
+has to be mapped to character B independently of a default mapping
+to uppercase or lowercase while character B must not be touched. I found
+this out the hard way ... Consider it a crude workaround, because Samba
+lacks the possibility to map characters in one direction only!
+
+VALIDCHR usually issues one warning for character 32.
+You may ignore these and any other warnings.
+
+VALIDCHR does not test for character NUL (this is the directory end marker).
+
+validchr.c is the source code to validchr.com
+ You may do anything with the source code (copy, change, sell, burn)
+validchr.com is a Borland C compiled binary.
+ Beware, it may contain a virus (if my system contains one).
+nwdos70.out is the output of an VALIDCHR-run under Novell DOS 7.0
+ while no codepage (no display.sys) was active.
+msdos70.out is the output of an VALIDCHR-run under MS-DOS 7.0 (Win95 DOS)
+ while codepage 850 was active.
+
+I have no other MS-DOS systems at home currently.
+(I have access to MS-DOS 3.0, 3.2, 3.3, 5.0 and 6.22, however I have no time
+ to run VALIDCHR there)
+
+Some words to the output
+(for people not fammiliar with programming language C):
+
+probed_char: [text] mapped_char
+
+probed_char is the character probed to be written to disk
+text may be empty or contain:
+ open File could not be opened.
+ close File could not be closed (should not happen)
+ length File name was shortened (usually occurs on SPC)
+ unlink File cannot be unlinked (usually when open fails)
+mapped_char is the character which is used by MS-DOS in the directory
+ This is usually the uppercase character.
+ The mapped character is 0 if something failed (you may say
+ that the character is not supported)
+
+The last line in the output is documented in the smb.conf manual page ;)
+
+tino@augsburg.net
diff --git a/examples/validchars/validchr.c b/examples/validchars/validchr.c new file mode 100644 index 0000000000..415546cb84 --- /dev/null +++ b/examples/validchars/validchr.c @@ -0,0 +1,123 @@ +/* by tino@augsburg.net
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <dirent.h>
+
+unsigned char
+test(void)
+{
+ DIR *dir;
+ struct dirent *dp;
+ unsigned char c;
+
+ if ((dir=opendir("."))==0)
+ {
+ perror("open .");
+ return 0;
+ }
+ c = 0;
+ while ((dp=readdir(dir))!=0)
+ {
+ size_t len;
+
+ len = strlen(dp->d_name);
+ if (len<4)
+ continue;
+ if (strcmp(dp->d_name+len-4, ".TST"))
+ continue;
+ if (len!=5)
+ {
+ fprintf(stderr, "warning: %s\n", dp->d_name);
+ printf(" length");
+ continue;
+ }
+ if (c)
+ printf(" double%d\n", c);
+ c = dp->d_name[0];
+ }
+ if (closedir(dir))
+ perror("close .");
+ return c;
+}
+
+int
+main(void)
+{
+ char name[256];
+ unsigned char map[256], upper[256], lower[256];
+ int i, j, c;
+ FILE *fd;
+
+ if (test())
+ {
+ printf("There are *.TST files, please remove\n");
+ return 0;
+ }
+ for (i=0; ++i<256; )
+ {
+ lower[i] = i;
+ upper[i] = 0;
+ }
+ for (i=256; --i; )
+ {
+ map[i] = i;
+ strcpy(name, "..TST");
+ name[0] = i;
+ printf("%d:", i);
+ if ((fd=fopen(name, "w"))==0)
+ printf(" open");
+ else
+ fclose(fd);
+ c = test();
+ if (unlink(name))
+ printf(" unlink");
+ if (c==i)
+ printf(" ok");
+ else
+ printf(" %d", c);
+ printf("\n");
+ if (c!=i)
+ {
+ upper[c]++;
+ lower[c] = i;
+ }
+ map[i] = c;
+ }
+
+ /* Uppercase characters are detected above on:
+ * The character is mapped to itself and there is a
+ * character which maps to it.
+ * Lowercase characters are the lowest character pointing to another one.
+ * Else it is a one way character.
+ *
+ * For this reason we have to process the list
+ * 1) for 'one way' characters
+ * 'one way' is something which is no upper and no lower character.
+ * This is an awful, crude and ugly hack due to missing Samba support.
+ * 2) for true uppercase/lowercase characters
+ * 3) for standalone characters
+ * Note that there might be characters which do not fall into 1 to 3.
+ */
+ printf("\n valid chars =");
+ for (i=0; ++i<256; )
+ if (map[i] && map[i]!=i && lower[map[i]]!=i)
+ {
+ if (!upper[i])
+ printf(" %d:%d %d:%d %d:%d", /*1*/
+ map[i], i, i, map[i], map[i], map[i]);
+ else
+ fprintf(stderr, "ignoring map %d->%d because of %d->%d\n",
+ lower[i], i, i, map[i]);
+ }
+ for (i=0; ++i<256; )
+ if (map[i] && map[i]==i)
+ if (upper[i])
+ printf(" %d:%d", lower[i], i); /*2*/
+ else
+ printf(" %d", i); /*3*/
+ printf("\n");
+ return 0;
+}
diff --git a/examples/validchars/validchr.com b/examples/validchars/validchr.com new file mode 100644 index 0000000000..a5dbb39bed --- /dev/null +++ b/examples/validchars/validchr.com @@ -0,0 +1,77 @@ +.0!.,ڣ . ] 3؋aC&8ùى +>#s>#>'r(>R#r"G;r>#t>R#u;wډ +؎JW!_ҋ3.&>'+>$#vG> r@w> r7X!r*g$#!r H!r@ HI!r +X!sb +t@p&3.&&6 6 6 Py.VW&&_^ËLF! 5! 5! 5! 5! %ʎں{!% !% !% !% !ø;t&?t&O2;sӃ;t&?&t&_&Wô;t&?t&8gr&gӃ;t&?&t&_&Wô@!ù .PPUVW!P6YFu
!PYF]VYsO!PPYYt8tV!P"P!PmY~tFP%!PWYYFvtYuvYt0!PYFt_^]UC +t
8!PY3aF^؊F^FF=|Fƍ^؊F^!PPYYFvd!PYYh!PPYYFu j!PvYFPJYtp!PeYF;Fu +x!PUYv|!PHYY!P?YF;Ft^^؊F^؊FNt2!PYFҍ^?u^؊;Fu鬍^؊؊;Fu鋍^؊uJ^؊P^؊P^؊Pvv^؊P!PZ0^؊Pvv^؊P!P"PwFF=} FW^?tI^؊;Fu7^?tv^؊P!Pv!PYYFF=|!]U>! u!F&!3]UC2V!r ^3P?]UCVN!r3P$]U/!SV!NNV!YZ!Qr3S]U/!SV!O!YZ!Qr3S]UVvu!!&>!u!~uu!!vY^]U3PPv]UP3Pv]3PP3PøPP3PyUVv|X~W6T#V#
ރ0T#6 ^]UVvV^]UD^!%]U"VW~ +^$wXrSFN}~t-Gٍv+F +FuNN, +s:FﰪF +_^]U3Pvv +PPaPj]U^で&#BF +^NV!rP]UVvVu.'vu#PVYYP#PVYY^]UVWv~V3P=uPFPVTYYt_^];$#s+LJ&#ڱƇ!!㉇!B;$#rՠ!PtYu&!P!t3P3P!PZ!P@Yu&!P!t3P3P!P&UAV!r3P]Ê'@'UVWFFPFFW2I_6GNu/SQRj+jPWvV +uFFP~jZY[j~~v +t<%t6GNv<%t~3ɉNNNFF2Ћ `s#v.wNЀwNŀw~+tV뵃fN 맀wMFu)N8~6FsyNFouFbsʵFU,0wF|F3uFtFNeNfY + + +FV3҈V~6 +FV~6GGvFt6GG~~uu~u6NRPWǘPFPSV}Vv~^67CC^F t6CC^:Z6FfN+ϋV;韉vV~6F~26vV~F u
6=F6=Fu#P;NvN酉vV~N}WQ^SR#FPFt F +FP~FtV~&=-uI+~V&=-tF +tO&~~ +N}N~^#F=ufou
~FxtXuN@KKn}FNFu yK;F@t0hFbV~'++&<-t< t<+u&CIK08+&6GN+~ ˰ Uv~F u6=F6=FP*FF&FtGG&v~% +u~P}~tF_^]^HS|A#'M
ntUVW~vY@PvW _^]UFԁ;s 3 ]UFV ҋur +;s ]UvY]UFRPYY]ú$$)$@!'.$@!UVDF^N +!r~uP]VW\r;X$tB_^9V$t#wt6X$ ;6V$t
TGX$
3V$X$Z$S[;V$twu?u2?t\ߋ;t>Z$wu|Z$Ë6Z$t|\]wÉZ$__VWDtRr6%=s>V$tZ$t
9s_;uf!397sk_^P3PP6[[%t 3RP([[XP3SP[[=t؉V$X$X@[3P3SP[[=tءX$GX$X@X3)7@\uËSPQP[tvVF$[^Ë;w5;X$uSPK[[]+)|Bˋ7كVWU^F +t7t-IЃs;rwO
PeS3[]_^&&UNCFV!rPy]UV;$#r PdLJ&#RY]U>^!rLJP5]UVWvYPYu + 3pvVYYOt߀8:t8\t +8/t\$a$PVYY/PYu VWPVtVYWY뙉u+E-E._^]UVv|.uVPt+D-^]UVv|.t + 3D-u VYuD-^]UVvt|.t D.t+YVY3^]UVW~td9}u_}t=} WVYuKEtuY}|EPWYEEE}t3PPuPYE_^]UVW~unf9}t^=|)Eu +9E +uF9E +u8EE +0.E@)5PEE +PEP +;t
EuM3_^]UVWF>$#!DtVbYFOuF_^]UVWvFF<ru wuau
F3iF+t<+uttbu+uFtu@buʀN#%Ћ©t@! ^^F_^]UVv +vFPFP4Dt |}'vFFPvD +}
DD3ADP'YtLPDt3P3PVtVYD^]V!||$#!փ;w||3^Uu3
Rvv3P$]UPvvFP]UVWv<} +TB3+ЋD@u,L +<} Iـ? +uGJuA? +uGJu_^]UVWv~ +V7YtGu<~V|)FVd_DD +WvvDPu +=u3_^]UVvP33PRDPUVFu=u鄃<}tD&#tWP33PRDPVFu=tP3PvvDPu
=u*FVFVVFVV)FVVF^]UVW~vNsF_^]UN<V!rP]U^++Ҵ@!]UVWv~uN#%3PvYYFtx#>P#ǩuP.~u#>T#t +6T#ǀt3Ft7PPtv3PO}WYvv6}lVvYY|Z3PW~YYFt ƀt%
PPW[ +tWFtttPPv|/t3ցRFt3ZЋ㉗&#_^]UNu +uV"N +=!rFF%
^㉇&#FP]U ;$}> | ㋗f$&Rv&P"PT]UP!PvFP]UVvVFPYY^]UVW~F<'=}:] +E +Eu><' +t +><'
tWYuڸEuEuMM}tE=t WeYuʋE؉] +E +<'Eu鈀><' +t><'
uzW2YtqmE&#tP33PREP><' +uE@uP&PEPO=uP<'PEP7=t +Eu=<'_^]U!PvYY]UVW~FFEt)W^FPYY=u3YFNuIE@u}u隋E;FsQ=t W=YuŊE&#tP33PREPvvEPn;FuF|=u ++EWYt`vvu +FFE +霊E&#tP33PREP!vvEP;Fta\}t=/}] +E +vFW^FPVYY=uFNuvvEP;FtF_^]UVWv~ +9tu~v馃>&u!u&>&u!u&<tP33PRVjDtt,YdDDD +~t>v:!B ~uWYFuuLlFD +D|~uL3_^]UVW~2u~+tIs_^]UVW؎3؋~2ыvD]+_^]UVW~2ы~F_^]UW؎~3H_]UVW~v;>$#r +PF@=s3Ӌ&#tP33PRW&#@uvVW訃霋で&#vFFMN^FF< +u
FFFx+Ё|'+VPW[;tu=F+F1x~ux+v!VxPW ;ttŋF+F_^]U^&#tP@^NV!rP^く&#XP]VW3!;>$#sDtVYG;>$#r_^VW!DtV"YOu_^Borland C++ - Copyright 1991 Borland Intl.Divide error
+Abnormal program termination
+>'>'.open ..TSTwarning: %s + length double%d +close .There are *.TST files, please remove +..TST%d:w open unlink ok %d + + valid chars = %d:%d %d:%d %d:%dignoring map %d->%d because of %d->%d + %d:%d %d + ! +!"C"B$"```@),(((((),(((),#,*((((**#(#%(TMP.$$$(null)
+ +
print scanf : floating point formats not linked
+\*.**.*$$$%%%%7%G%\%n%%%%%%%%&&#&4&E&W&i&j&k&l&m&n&o&p&q&r&s&&&&&&&&&&&&&&&0Error 0Invalid function numberNo such file or directoryPath not foundToo many open filesPermission deniedBad file numberMemory arena trashedNot enough memoryInvalid memory block addressInvalid environmentInvalid formatInvalid access codeInvalid dataNo such deviceAttempted to remove current directoryNot same deviceNo more filesInvalid argumentArg list too bigExec format errorCross-device linkMath argumentResult too largeFile already existsPossible deadlockUnknown error%s: %s |