#!/usr/bin/perl -- # # Set up Windows directories for Samba PCs in ~: # ~/Windows for configuration data which is accessed direct from the PC # ~/My_Documents for the user's visible files, accessed directly # ~/.profiles for the WinXP roaming profile which is copied at login/logout # ~/.profiles.V2 for the Win7 roaming profile which is copied at login/logout # # For the moment the argument is /users/%g/%u/.profiles -- change that later # The argument is defined in smb.conf and is "wrong" at Win7 ... but does not matter. ( $cmd = $0 ) =~ s!.*/!!; eval { ( $group, $user ) = $ARGV[0] =~ m!^/users/(.+?)/(.+?)/.profiles$! or die "Bad argument $ARGV[0]\n"; -e "/usr/sms.$_" and $host = $_, last foreach qw( rome bianco newrome newbianco ); $host or die "Bad host (must be bianco or rome)\n"; ## Undergrad group names are alpha followed by a single digit, ## thus e.g. mc2stuff or gen21 or st5 are NOT undergrads. #$is_undergrad = ( ( $host ne 'bianco' ) && ( $group =~ m!^[a-z]+[0-4]$! ) ); # Undergrad usernames contain a digit: see also siv:/s/SMS/User.pm $is_undergrad = ( $user =~ m!\d! ); # logmsg( "called for $user.$group" ); umask 077; chdir "/users/$group/$user" or die "Could not chdir to /users/$group/$user\n"; $group eq 'cap' || $user eq 'conf' and ! -w "/users/$group/$user" and exit; # Rarely we end up with ".profiles/Local Settings": sign that # profile is corrupted, or will be soon? Remove it. foreach( '.profiles/Local Settings', '.profiles.V2/AppData/Local', '.profiles.V2/AppData/LocalLow' ) { if( -e $_ ) { logmsg( "Removing unwanted /users/$group/$user/$_" ); system( "rm", "-rf", $_ ); } } # Rarely we end up with ".profiles/prf*.tmp" files (would be # NTUSER.DAT but not renamed yet)? foreach( glob( ".profiles/prf*.tmp" ), glob( ".profiles/*/prf*.tmp" ), glob( ".profiles.V2/prf*.tmp" ), glob( ".profiles.V2/*/prf*.tmp" ) ) { unlink $_; logmsg( "Removed unwanted /users/$group/$user/$_" ); } # Rarely we have ".profiles/ntuser.dat", rename to NTUSER.DAT for # uniformity (though at WinXP it seems the "default" is lowercase) foreach( '.profiles', '.profiles.V2' ) { if( -e "$_/ntuser.dat" ) { if( -e "$_/NTUSER.DAT" ) { logmsg( "Both ntuser.dat and NTUSER.DAT in /users/$group/$user/$_" ); } else { logmsg( "Renaming /users/$group/$user/$_/ntuser.dat as NTUSER.DAT" ); rename "$_/ntuser.dat", "$_/NTUSER.DAT"; } } # Same for "ntuser.dat.LOG". Funny that capitalization... if( -e "$_/ntuser.dat.LOG" ) { if( -e "$_/NTUSER.DAT.LOG" ) { logmsg( "Both ntuser.dat.LOG and NTUSER.DAT.LOG in /users/$group/$user/$_" ); } else { logmsg( "Renaming /users/$group/$user/$_/ntuser.dat.LOG as NTUSER.DAT.LOG" ); rename "$_/ntuser.dat.LOG", "$_/NTUSER.DAT.LOG"; } } } # Is this a "good" profile worth saving? # Should we (also) check the existence of ntuser.ini? foreach( '.profiles', '.profiles.V2' ) { if( ( -s "$_/NTUSER.DAT") > 256*1024 ) { if( $cmd =~ m/unset/ ) { # Only cleanup above, do nothing else for unset-profile at disconnect } else { # This is "good", save it $MNTUSER = -M _; $Msaved = -M "$_-saved.tgz"; if( $MNTUSER > 0 and $Msaved > 0 and $MNTUSER > $Msaved ) { #logmsg( "Not saving, /users/$group/$user/$_-saved.tgz newer than NTUSER.DAT" ); } else { #logmsg( "Saving to /users/$group/$user/$_-saved.tgz" ); # Do not save $_/Desktop: sometime too large. (Should be moved to ~/Windows instead.) # Do not save $_/MyDocuments: sometimes large, and wrongly still in .profiles and .profiles.V2 . # Do not save $_/ApplicationData: often large, and we do not really need. # Names are Documents and AppData for Win7. # Should not we save just NTUSER.DAT and maybe NTUSER.DAT.LOG ? system( "tar zcf $_-saved.tgz $_ --exclude=$_/Desktop --exclude='$_/My Documents' --exclude='$_/Documents' --exclude='$_/Application Data' --exclude='$_/AppData' >/dev/null 2>/dev/null" ); } } } # Otherwise is there a good saved profile? elsif( ( -s "$_-saved.tgz" ) > 20*1024 and 0 == system( "gunzip -t $_-saved.tgz >/dev/null 2>/dev/null" ) ) { if( $cmd =~ m/unset/ ) { # Only cleanup above, do nothing else for unset-profile at disconnect logmsg( "Should restore /users/$group/$user/$_-saved.tgz" ); } else { # Saved is good, restore it logmsg( "Restoring /users/$group/$user/$_-saved.tgz" ); # Do not pre-remove: we did not save everything in $_ (see above). #system( "rm -rf $_" ); # We used to have ">&- 2>&-" so as not to be bothered by bogus output; # but "tar zxf" does not seem to like that, would whinge # "gzip: stdout: Bad file descriptor" and fail. Instead use # ">/dev/null 2>/dev/null" (though "tar zcf" does not seem to mind). system( "tar zxf $_-saved.tgz $_ >/dev/null 2>/dev/null" ); } } } # Only cleanup above, do nothing else for unset-profile at disconnect $cmd =~ m/unset/ and exit; # Unlikely this would ever happen after our restore above... # # Avoid problems with empty NTUSER.DAT file (left like that when # logging out with disk quota exceeded): remove so default one # can be created. # With an empty NTUSER.DAT, the user would get the error message # # Windows cannot load the locally stored profile. Contact your # network administrator. # DETAIL: the system has attempted to load or restore a file into # the registry, but the specified file is not in a registry file # format. # ... # Windows cannot load the profile and is logging you on with a # temporary profile. # Changes you make to this profile will be lost when you log off. # # With a missing NTUSER.DAT, the user's profile is not copied in; at # logout a default NTUSER.DAT and profile are written out; thus any # customizations to the profile are lost. # This also occurs for new users: the seeding of profiles does not # work on first login. See profile-ok.sms below also. # # Empty prefs.js files are (silently) picked up later. # # Any way of alerting the user (e.g. WinPopup with smbclient)? # Used to do this also when logging out, not only when logging in. # Want to alert anyway? (Users would needlessly ask for backups.) foreach( '.profiles/NTUSER.DAT', '.profiles.V2/NTUSER.DAT' ) { if( -f $_ and ! -s _ ) { unlink $_; logmsg( "Removed empty /users/$group/$user/$_" ); } } # Bad profiles often have NTUSER.DAT of exactly 256kB. Complain, but # not after very first login when we never yet had a good profile. foreach( '.profiles', '.profiles.V2' ) { if( ( -s "$_/NTUSER.DAT") == 256*1024 and ( -s "$_-saved.tgz" ) > 20*1024 ) { logmsg( "Should remove /users/$group/$user/$_/NTUSER.DAT of 262144 bytes" ); } } # On first login, we must make the .profiles directory. Paul points out # we also need to create some other directories, as if Windows does so it # will use inappropriate permissions. # 2 Nov 2001 (PSz) With Samba 2.2.1a I cannot see a permissions problem, # though we do not use any of # restrict acl with mask = yes # security mask = 0000 # directory security mask = 0000 # force security mode = 0600 # force directory security mode = 0700 # nor even # inherit permissions = Yes # in smb.conf, but have only # create mask = 0600 # directory mask = 0700 # force create mode = 0600 # force directory mode = 0700 # Still we need to pre-create some directories, as Windows attempts to # write files/dirs without creating the tree above. (In some cases it # tries again and creates the tree, but we do not like samba to whinge.) unless( $is_undergrad ) { makedirs_from_path( ".profiles/$_" ) foreach 'Start Menu/Programs/Startup/', 'Start Menu/Programs/Accessories/System Tools/', 'Start Menu/Programs/Accessories/Entertainment/', 'Start Menu/Programs/Accessories/Accessibility/', 'Favorites/Media/', 'Favorites/Links/', 'Desktop/', 'Application Data/Adobe/Acrobat/WHAPI/', 'Application Data/Microsoft/Crypto/RSA/', 'Application Data/Microsoft/Excel/XLSTART/', 'Application Data/Microsoft/FrontPage/State', 'Application Data/Microsoft/Internet Explorer/', 'Application Data/Microsoft/Office/Recent/', 'Application Data/Microsoft/Protect/', 'Application Data/Microsoft/SystemCertificates/My/', 'Application Data/Microsoft/Word/STARTUP/', 'Application Data/Identities/', 'My Documents/My Pictures/'; } ##### What is it we need for Win7 and .profiles.V2 ? # Should have # [HKEY_CURRENT_USER\Software\Adobe\Acrobat Reader\11.0\JSPrefs] # "bEnableJS"=dword:00000000 # [HKEY_CURRENT_USER\Software\Adobe\Acrobat Reader\11.0\Originals] # "bAllowOpenFile"=dword:00000000 # [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Adobe\Acrobat Reader\11.0\TrustManager] # "bEnhancedSecurityStandalone"=dword:00000001 # "bEnhancedSecurityInBrowser"=dword:00000001 # "bDisableTrustedFolders"=dword:00000001 # "bDisableTrustedSites"=dword:00000001 # "bDisableOSTrustedSites"=dword:00000001 # "iProtectedView"=dword:00000002 # set in Mike's policies. # I see the registry setting for "Enable External Streams", but # where is "Allow multimedia operations" (and are they dangerous)? # See: # http://rome/u/psz/securepc.html#Acrobatx # /usr/sms/bin/acroreadn # http://www.adobe.com/devnet-docs/acrobatetk/tools/AppSec/index.html # http://www.adobe.com/devnet-docs/acrobatetk/tools/PrefRef/Windows/index.html #makedirs_from_path( '.profiles/Application Data/Adobe/Acrobat/7.0/JavaScripts/glob.settings.js/' ); if( $is_undergrad ) { # Mike will make Word user templates be written there for students makedirs_from_path( "Windows/.office/" ); } if( $host eq 'bianco' ) { # Mike want this for admin users makedirs_from_path( "Windows/Lotus/Backups/" ); } # For proper permissions makedirs_from_path( 'My_Documents/My_Pictures/' ); if( $host eq 'bianco' ) { # Set up Admin database reports files makedirs_from_path( "My_Documents/db/reports/$_/" ) foreach qw( staff ); } foreach( '.profiles/Start Menu/Programs/Startup/desktop.ini', '.profiles/Start Menu/Programs/Startup/Desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Internet Explorer/Quick Launch/User Pinned/TaskBar/desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Internet Explorer/Quick Launch/desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Windows/Libraries/desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Windows/Recent/desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Windows/SendTo/Desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Accessories/Accessibility/Desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Accessories/Desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Accessories/System Tools/Desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Administrative Tools/desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Maintenance/Desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup/desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/desktop.ini', '.profiles.V2/AppData/Roaming/Microsoft/Windows/Start Menu/desktop.ini', '.profiles.V2/Contacts/desktop.ini', '.profiles.V2/Desktop/desktop.ini', '.profiles.V2/Downloads/desktop.ini', '.profiles.V2/Favorites/Links/desktop.ini', '.profiles.V2/Favorites/desktop.ini', '.profiles.V2/Links/desktop.ini', '.profiles.V2/Music/desktop.ini', '.profiles.V2/Saved Games/desktop.ini', '.profiles.V2/Searches/desktop.ini', '.profiles.V2/Videos/desktop.ini' ) { if( -f $_ ) { unlink $_; logmsg( "Removed annoying /users/$group/$user/$_" ); } } # Flag so we (i.e. Mike's login scripts) can recognize when # the seeding of the profiles did not work. #provide_file( '.profiles/profile-ok.sms', '' ); # More useful than just an empty flag file: # store disk quota info there, so can maybe parse later. # May be unable to write contents when over quota... system( "/usr/sms/bin/quota -v >.profiles/profile-ok.sms 2>&1" ); system( "cp .profiles/profile-ok.sms .profiles.V2/profile-ok.sms 2>&1" ); # For Firefox 1.5.X ... 8.0.X # Might do even without installing (Thunderbird also?), see # http://lists.grok.org.uk/pipermail/full-disclosure/2004-November/028772.html # : # >> Can the Firefox settings be controlled centrally? # > ... Download Firefox 1.0.zip, unpack it to R/O share on file server, # > edit JS configuration files in .\defaults\pref and .\greprefs, then # > create a shortcut to firefox.exe on user desktops. To change FF # > settings, edit JS configs again. Voila! # Run L:\win\sfwinst\DataOnly\FirefoxSetup-3.0.X.exe and do: # accept licence, # Standard install (or Custom without "Quality Feedback Agent"?) # in C:\Program Files\Mozilla Firefox. # Start firefox (as admin), as that still creates a few things. # User might want to copy his latest bookmarks file e.g. # ~/Windows/.netscape7/bookmarks.html # to # ~/Windows/.firefox/ # at any time (but not while firefox is running). # There is some slowness on first use of FF ... # and two tabs at upgrade or version change ... # FF3 uses not bookmarks.html but places.sqlite, and does the automatic # translation or seeding only if there is no inaccessible bookmarkbackups # object. Use urlclassifierkey3.txt as a flag whether we need this. foreach( '.profiles/Application Data/Mozilla/Firefox/profiles.ini', '.profiles.V2/AppData/Roaming/Mozilla/Firefox/profiles.ini' ) { provide_file( $_, < 1500; # Must be newer than we had already next unless ( -M _ ) < $M; $M = ( -M _ ); $FFbak = $_; } if( $FFbak ) { logmsg( "Restoring /users/$group/$user/$FFbak" ); system( "cp", $FFbak, $FFprefs ); } } # Generate FF preferences and bookmarks based on NS7. # Could check if NS7 settings are newer, and re-create. # Not really needed: we have "static" FF preferences; user can # easily copy his latest bookmarks file. # if( -f $FFprefs ) # { # $M = -M _; # if( -f $NS7prefs and $M > -M _ ) # { # # logmsg( "/users/$group/$user/$FFprefs is older than $NS7prefs" ); # # The FF file is older than the NS7 one: # # is unused yet, the default we gave some time ago? # eval # { # opendir D, $FFdir or die "Cannot opendir $FFdir\n"; # while( $_ = readdir D ) # { # m/^(\.|\.\.|Cache|Cache\.Trash|XUL.mfl|compreg.dat|compreg.dat.tmp|prefs.js|bookmarks\.html)$/ or # die "Unexpected file $_ in $FFdir\n"; # } # closedir D or die "Cannot closedir $FFdir\n"; # }; # unless( $@ ) # { # logmsg( "Removing unused /users/$group/$user/$FFprefs ($NS7prefs is newer)" ); # unlink $FFprefs; # # Test newness of bookmarks? # # Or is it "cheaper" to recreate anyway? # unlink $FFbookmark; # } # } # } unless( -f $FFprefs && -s _ ) { setup_VAL(); ## Tempting to copy NS7 preferences, but do not want to keep ## directory settings. Do afresh, from scratch. # # Keep NS7 preferences. # # Some (mail, news etc) lines are not needed/used by FF: strip them out? # open F, $NS7prefs and ( # $prefs = join( '', ), # close F or die "Cannot close $NS7prefs (to copy to $FFprefs)\n" # ); # $prefs .= < ), # close F or die "Cannot close $NS7bookmark (to copy to $FFbookmark)\n" #); #$bookmark or $bookmark = < Bookmarks

Bookmarks

Personal Toolbar Folder

School

SMSsearch
scnews
calendar
scwho
Research
Teaching
Administration
Digital Alpha

Usyd

University of Sydney
University of Sydney Search
Electronic Phone Book
Library catalogue search

EO provide_file( $FFbookmark, $bookmark ); } } if( $is_undergrad ) { # Undergraduates don't need https (except for MyUni) so don't get # certificates. Others may need this ... unlink "$FFdir/cert8.db"; } # Be double-safe even with browser.cache.disk.capacity set to 0 foreach( "$FFdir/Cache", "$FFdir/Cache.Trash", "$FFdir/OfflineCache", "$FFdir/XPC.mfasl", "$FFdir/XPC.mfl", "$FFdir/XUL.mfasl", "$FFdir/XUL.mfl", "$FFdir/compreg.dat", "$FFdir/compreg.dat.tmp", "$FFdir/startupCache", "$FFdir/thumbnails", "$FFdir/urlclassifier2.sqlite", #"$FFdir/urlclassifier3.sqlite", # FF12 tries and times out and slows down, cannot cope without ) { make_empty0file( $_ ); } foreach( "$FFdir/urlclassifier3.sqlite", # Checked from FF15 only: (would clobber symlink to /dev/null,) can handle empty dir (with whatever permissions) ) { make_empty0dir( $_ ); } # FF3 uses not bookmarks.html but places.sqlite, and does the automatic # translation or seeding only if there is no inaccessible bookmarkbackups # object. Use urlclassifierkey3.txt as a flag whether we need this. if( -e "$FFdir/urlclassifierkey3.txt" ) { make_empty0file( "$FFdir/bookmarkbackups" ); } else { # Remove a file, leave a directory alone unlink "$FFdir/bookmarkbackups"; } # For Thunderbird 1.5.X ... 8.0.X # Run L:\win\sfwinst\DataOnly\ThunderbirdSetup-2.0.X.exe and do: # accept licence, # Standard install (or Custom without "Quality Feedback Agent"?) # in C:\Program Files\Mozilla Thunderbird. # Start thunderbird (as admin), as that still creates a few things. # User should start thunderbird (to create mail directory structure), # then quit. Copy mail files and address books e.g. # ~/Windows/.netscape7/Mail/rome/Inbox # ~/Windows/.netscape7/abook.mab # to # ~/Windows/.thunderbird/Mail/rome/ # ~/Windows/.thunderbird/ # respectively. (*.summary or *.msf files should not be copied; the # TB *.msf files could be dropped to ensure they are re-created.) # If you have more than just the one abook.mab, then in thunderbird # pre-create new, empty ones named abook-N.mab with # address book, file, new, address book # then copy them on top. # For NS4 users, the mail files e.g. # ~/Windows/.netscape/mail/Inbox # can be copied as above. But thunderbird does not understand the # ~/Windows/.netscape/pab.na2 files: use NS7 to import and convert # to *.mab format. # When starting from UNIX NS4, the ~/nsmail/Inbox files will need # to get DOS-like line termination e.g. with # perl -i.bak -pe 's/\r/$/' Inbox Outbox # while it seems that the UNIX ~/.netscape/pab.na2 address book cannot # be "fed" to Windows NS7 to convert to abook.mab format. foreach( '.profiles/Application Data/Thunderbird/profiles.ini', '.profiles.V2/AppData/Roaming/Thunderbird/profiles.ini' ) { provide_file( $_, < -M _ ) # { # # logmsg( "/users/$group/$user/$TBprefs is older than $NS7prefs" ); # # The TB file is older than the NS7 one: # # is unused yet, the default we gave some time ago? # eval # { # opendir D, $TBdir or die "Cannot opendir $TBdir\n"; # while( $_ = readdir D ) # { # m/^(\.|\.\.|XUL.mfl|compreg.dat|compreg.dat.tmp|prefs.js)$/ or # die "Unexpected file $_ in $TBdir\n"; # } # closedir D or die "Cannot closedir $TBdir\n"; # }; # unless( $@ ) # { # logmsg( "Removing unused /users/$group/$user/$TBprefs ($NS7prefs is newer)" ); # unlink $TBprefs; # unlink $TBaddrbook; # } # } # } unless( -f $TBprefs && -s _ ) { setup_VAL(); ## Tempting to copy NS7 preferences, but do not want to keep ## directory settings. Do afresh, from scratch. # # Keep NS7 preferences. # # Only mail lines are needed/used by TB: strip others out? # open F, $NS7prefs and ( # $prefs = join( '', ), # close F or die "Cannot close $NS7prefs (to copy to $TBprefs)\n" # ); # $prefs .= < ), # close F or die "Cannot close $NS7addrbook (to copy to $TBaddrbook)\n" # ); # $addrbook and provide_file( $TBaddrbook, $addrbook ); #} } else { # There is $TBprefs file already: check/set auth_method=0 # See /usr/sms/bin/thunderbird and RT ticket #4403 also # Is the problem that: # with mail.smtpserver.smtp1.username set, thunderbird always tried a login; # up until etch, rome did not know how to handle usernames and accepted; # but since lenny, rome sendmail complains # Dec 22 18:48:27 rome sm-mta[6666]: unable to open Berkeley db /etc/sasldb2: No such file or directory # and fails. # We should never have set smtp1.username ... # # Rome sendmail was allowing/offering AUTH, as seen by: # psz@bari:~$ /usr/bin/telnet rome 25 # (and saying "ehlo x" then quit). # I have now removed Debian package libsasl2-modules with: # root@rome:~# apt-get remove libsasl2-modules # and restarted sendmail, and now rome does not offer AUTH anymore. # Package libsasl2-modules was installed on rome only (nowhere else). I do # not know what else it might have been used for (or why it was on rome). # # Another way of "stopping" AUTH seems to be to add the line # SRV_Features: A # to file /etc/mail/access , see # http://www.sendmail.org/documentation/installGuide # http://www.sendmail.org/doc/sendmail-current/doc/op/op.pdf $pref = ''; open F, "<$TBprefs" and ( $pref = join( '', ), close F ); $repl = 0; # BEWARE: some people use multiple smtp servers, or other than mh ... if( $pref and $pref !~ m/\"mail.smtpserver.smtp\d.hostname\",\s*\"(?!mh\")/ ) { $pref =~ s/(\"mail.smtpserver.smtp1.auth_method\",)\s*[1-9]\d*/$1 0/ and $repl = 1; $pref !~ m/auth_method/ and $pref .= "user_pref(\"mail.smtpserver.smtp1.auth_method\", 0);\n" and $repl = 1; $pref =~ s/^(user_pref\(\"mail.smtpserver.smtp1.username\",\s*\"\w+\"\);\s*)$/\/\/$1/m and $repl = 1; } if( $repl ) { -e "$TBprefs.pre-auth" or system( "cp", $TBprefs, "$TBprefs.pre-auth" ); provide_file( $TBprefs, $pref ); } } if( $is_undergrad ) { # Undergraduates don't need https (except for MyUni) so don't get # certificates. Others may need this ... unlink "$TBdir/cert8.db"; } # Be double-safe even with browser.cache.disk.capacity set to 0 # and nglayout.debug.disable_xul_cache set to true. foreach( #"$TBdir/Cache", #"$TBdir/Cache.msf", #"$TBdir/Cache.sdb", "$TBdir/XPC.mfasl", "$TBdir/XPC.mfl", "$TBdir/XUL.mfasl", "$TBdir/XUL.mfl", "$TBdir/compreg.dat", "$TBdir/compreg.dat.tmp" ) #"$TBdir/startupCache", #"$TBdir/startupCache.msf", #"$TBdir/thumbnails", #"$TBdir/urlclassifier2.sqlite", #"$TBdir/urlclassifier3.sqlite", # FF12 tries and times out and slows down, cannot cope without { make_empty0file( $_ ); } #foreach( # "$TBdir/urlclassifier3.sqlite", # Checked from FF15 only: (would clobber symlink to /dev/null,) can handle empty dir (with whatever permissions) #) #{ # make_empty0dir( $_ ); #} }; if( $err = $@ ) { ## unless ($group eq 'cap' and $err =~ /^Could not open .* \(permission denied\)$/) { logmsg( "died for $user.$group: $err" ); ## } die $err; } ## sub makedirs_from_path { my ( $path ) = @_; # Recursively make directories under the mount point required for $path, # which may be a file path (the file component is irrevelant) or a # directory path ending in /. $path =~ s!^(.+)/[^/]*$!$1! and # remove file component or trailing / ! -d $path and # stop if directory already exists makedirs_from_path( $path ), # make the ancestor directories mkdir( $path, 0700 ) || # make the bottom directory die "makedirs_from_path: cannot mkdir $path (\l$!)\n"; } sub provide_file { my ( $file, $cont ) = @_; makedirs_from_path( $file ); open( F, ">$file" ) or die "Could not open $file (\l$!)\n"; $cont =~ s!\r?\n!\r\n!g; print F $cont or die "Could not print $file (\l$!)\n"; close F or die "Could not close $file (\l$!)\n"; } sub make_symlink { my ( $tgt, $lnk, $quiet ) = @_; lstat( $lnk ); if( -e _ ) { return if -l _ and readlink($lnk) eq $tgt; logmsg( "Removing, re-creating /users/$group/$user/$lnk -> $tgt" ) unless $quiet; unlink $lnk; system( "rm", "-rf", $lnk ) if -e $lnk; } makedirs_from_path( $lnk ); symlink( $tgt, $lnk ) or die "Could not symlink $lnk -> $tgt (\l$!)\n"; } sub make_empty0file { my ( $f ) = @_; if( -e $f ) { return if -f _ and ! -s _; logmsg( "Removing, re-creating /users/$group/$user/$f" ); unlink $f; system( "rm", "-rf", $f ) if -e $f; } provide_file( $f, '' ); chmod( 0000, $f ) or die "Cannot chmod 0 $f\n"; } sub make_empty0dir { my ( $f ) = @_; if( -e $f ) { return if -d _; # No fast and easy check that the directory is empty logmsg( "Removing, re-creating /users/$group/$user/$f" ); unlink $f; } makedirs_from_path( "$f/" ); chmod( 0000, $f ) or die "Cannot chmod 0 $f\n"; } sub setup_VAL { return if defined $VAL{ USER }; %VAL = ( USER => $user, GROUP => $group, FULLNAME => ( getpwnam $user )[6], WINDIR => 'H:\Windows', NOW => time, ); } sub logmsg { require WireSyslog; WireSyslog::syslog_options( IDENT => ( $cmd || 'setup-or-unset-profile' ), PID => 1 ); WireSyslog::slog( @_ ); } #!#