#!/usr/bin/perl # this script runs testparm on all the files listed in # @allconfs and generates a tab delimited list of all shared # that could be possibly defined on your system. # this is needed because on some setups, not all service # definitions are known, and ones that are not in use do not # show up in, for example, smbstatus. # # run this as follows: # make_share_list_file > SAMBALOCKDIR/share_list # # where SAMBALOCKDIR is /usr/local/samba/var/lock by default # but I use /var/lock/samba (for RH) # set $minrealuid to the smallest uid actually used on your system # this is used to figure home directory shares # any uid less than this will be ignored # (so the bin,lp,mail, etc users arn't included) $minrealuid = 500; # set to where testparm is installed $TESTPARM = '/usr/bin/testparm'; # set @allconfs to the list of configuration files you use to # define shares for samba. I make heavy use of include # parameters, and I have a lot of shares defined in separate files # You can most likely get away with the following if you have a # simple setup: @allconfs = ('/etc/smb.conf'); # my setup is more complex: # # @confs1 = ('/etc/smb.conf', # '/etc/smb.conf.jupiter', # ); # # @confs2 = `find /shares/00perms/Shares /shares/00perms/Dept -type f`; # chomp @confs2; # # @allconfs = (@confs1, @confs2); %shares = (); $homes_share_exists = 0; foreach $conffile (@allconfs) { open(T, "$TESTPARM $conffile < /dev/null |"); $type = "disk"; while (!eof(T)) { $line = ; chomp $line; # a series of runs through testparm are all collected together, which means that global # parameters are also listed between shares. testparm outputs the string # Global before # the global parameter listing. &remember_share if ($line =~ m/^# Global/); if ($line =~ m/^\[.+\]/) { &remember_share; ($share) = $line =~ m/^\[(.+)\]/; if ($share eq 'homes') { # skip this for now, we'll add entries for all home directories later on $homes_share_exists = 1; $share = ''; $path = ''; $comment = ''; next; } } if ($line =~ m/^\s+path =/) { ($path) = $line =~ m/^\s+path = (.+)$/; $type = "cdrom" if ($path =~ m@/cdrom@); next; } if ($line =~ m/^\s+comment =/) { ($comment) = $line =~ m/^\s+comment = (.+)$/; next; } if ($line =~ m/\s+printable =/ || $line =~ m/print ok =/) { $type = "printer" if (&contains_truth_string($line)); next; } } &remember_share; close(T); } unlink $TMPFILE; if ($homes_share_exists) { setpwent; while (($name, $j, $uid, $j, $j, $j, $j, $dir, $j) = getpwent) { if ($uid >= $minrealuid && -e $dir ) { $shares{$name} = $dir; $types{$name} = 'home'; } } endpwent; } foreach $share (sort keys %shares) { $path = $shares{$share}; $type = $types{$share}; $comment = $comments{$share}; print "$path\t$share\t$type\t$comment\n"; } sub contains_truth_string { my($st) = @_; return $st =~ m/(yes|true)/i; } sub remember_share { if ($share && $path) { $shares{$share} = $path; $types{$share} = $type; $comments{$share} = $comment; $share = ''; $path = ''; $comment = ''; $type = 'disk'; } }