Advertisement
GeorgeT93

folder-owner-enforcer

Mar 24th, 2019
394
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 58.46 KB | None | 0 0
  1. #!/bin/bash
  2. SCRIPT_VER="Folder Owner Enforcer v0.5.3a"
  3.  
  4. # Written by
  5. # reddit: https://www.reddit.com/user/GeorgeT93
  6. # pastebin: https://pastebin.com/u/GeorgeT93
  7. # script pastebin: https://pastebin.com/qRSWAKp1
  8.  
  9. # ==========================================================================================================
  10.  
  11. # NOTES - START
  12.  
  13. # REQUIREMENTS:
  14.  
  15. #    - inotify-tools (For Raspbian: sudo apt-get install inotify-tools)
  16. #    - The user used to create and invoke the script must have sudo privileges.
  17.  
  18. # LATEST UPDATE INFO
  19.  
  20. # v0.5.3a Update (2019-04-05) - Added code to identify logged in users when deletions are
  21. # detected. This is just to let admins know who was logged in at the time a file or folder
  22. # was deleted. This functionality can be disabled by changing the SHOW_USERS_ON_DELETE
  23. # value to disabled (0) in the advanced options in the user-defined variables section.
  24. # If your distribution does not have the following commands available, or if their output
  25. # deviates dramatically from Debian-based distributions, then disable SHOW_USERS_ON_DELETE.
  26. # The commands used to identify users are ps, grep, tr and awk.
  27.  
  28. # v0.5.2a Update (2019-04-04) - Added logic to determine if a new item in the root folder
  29. # is a file or a folder. This prevents the script from restarting when it's just a file
  30. # that was detected, as nothing is enforced on items in the root folder. Also added a 5
  31. # second delay to the function that terminates other running instances of the script in
  32. # order to give the system time to properly close the existing inotifywait instance
  33. # (rather than killing it prematurely.)
  34.  
  35. # v0.5.1a Update (2019-04-03) - Fixed issue with logfile not creating a new file on events
  36. # that occurred on different dates. Also fixed the extra whitespace issue when a newly
  37. # detected file or folder name did not contain any spaces in the path. Finally, the script
  38. # now records file deletions that occur in monitored folders.
  39.  
  40.  
  41. # GENERAL INFORMATION
  42.  
  43. # This script scans the directories located in ROOTPATH, and retrieves owner and group info
  44. # for each. It then monitors the ROOTPATH (recursively) for any added files or directories,
  45. # and when new ones are detected, the script changes the ownership and group of the file
  46. # or directory to the owner and group of the directory that it was placed in, and then sets
  47. # any defined permissions.
  48.  
  49. # I wrote it because I have a small SFTP server with only a couple of users, but I kept
  50. # having issues when putting files into a user's directory, as they were unable to be
  51. # downloaded because the ownership and group of the file were set to my admin user.
  52. # As such, I had to remind myself to change the ownership of anything I put into a user's
  53. # folder every time or I would get the inevitable phone call or text telling me the file(s)
  54. # couldn't be downloaded.
  55.  
  56. # With this script, when anything is put in someone's folder, the item is given the ownership and
  57. # group of the folder it was placed/created in, and the defined permissions mask is applied,
  58. # regardless of how deep in a user's folder the item was placed. I wrote it to solve an issue when,
  59. # for example, user1 uploaded files into a new folder in user2's or user3's folder. The new FOLDER
  60. # had the correct owner, group and permissions, but the files IN the new folder did NOT have the
  61. # right permissions (everything was read-only by other group members.) However, if user1 put the
  62. # files directly into a user's base folder (not in a new sub-folder), all the permissions were
  63. # applied correctly. Since I typically drop files directly into a user's folder from a mapped drive
  64. # on my local network, anything I put into any user's folder would have the ownership and group set
  65. # to my "admin" user, even though my admin user account is a member of the sftp group that all other
  66. # users are members of. Since I couldn't find another way to do it, I decided to write this script
  67. # to do it for me.
  68.  
  69.  
  70. # COMMAND LINE OPTIONS
  71.  
  72. # Command line options - If you invoke the script with no arguments, then the values set in this
  73. # script will be used for all functions. You can over-ride some of the settings in the script using
  74. # command line arguments. The full list of arguments can be seen by typing:
  75. #     folder-owner-enforcer --help
  76.  
  77. # NOTES - END
  78.  
  79. # ==========================================================================================================
  80.  
  81. # INSTALLATION - START
  82.  
  83. # As the script was written on and for a Raspberry Pi, the following instuctions assume
  84. # Raspbian Stretch as the distribution. The script should work on other distributions
  85. # that inotify-tools runs on, but note that some commands and/or paths may be different.
  86.  
  87. # 1.) If inotify-tools is not installed, use the following command (on Raspbian)
  88. #     $    sudo apt-get install inotify-tools
  89.  
  90. # 2.) Change to the /usr/local/bin folder
  91. #     $    cd /usr/local/bin
  92.  
  93. # 3.) Create the file and open it in edit mode
  94. #     $    sudo nano folder-owner-enforcer
  95.  
  96. # 4.) Paste the script into the open file
  97.  
  98. # 5.) Edit the USER-DEFINED VARIABLES section, setting the values you wish to use. Be aware the the
  99. #     LOGFILEPATH= value is set to /tmp by default. The /tmp directory is cleared on each system restart,
  100. #     so if you wish to maintain copies of the log files, you should point the LOGFILEPATH= value to the
  101. #     directory you wish to store your logs. If you decide to keep logs long-term, you should think of
  102. #     either offloading them to another system for archival purposes (if needed), or creating a cron job
  103. #     to run at a regular interval to clean up old, unwanted logs. For my setup, I don't need to retain
  104. #     any old logs, as I am usually only concerned with the last job run, so using the /tmp folder for
  105. #     logging works for my particular requirements.
  106.  
  107. # 6.) Save (<ctrl>+o) and exit (<ctrl>+x) the nano editor
  108.  
  109. # 7.) Set the script to executable
  110. #     $    sudo chmod +x folder-owner-enforcer
  111.  
  112. # 8.) Set up auto run using one of the following methods (DO NOT USE BOTH)
  113.  
  114. #     Method 1 - (Using cron) This is the preferred method as it essentially runs invisibly to the user.
  115.  
  116. #        8_1a.) Launch the crontab editor
  117. #               $    crontab -e
  118.  
  119. #        8_1b.) Add the following line to the bottom of the file, substituting the user you wish to run the
  120. #               script as. You MUST define a user that has sudo permission and you should NOT use the root
  121. #               user. The user defined in the command below is 'pi', so you would switch 'pi' to your user's
  122. #               name.
  123. #                   @reboot -u pi /usr/local/bin/folder-owner-enforcer
  124.  
  125. #        8_1c.) Save (<ctrl+o>) and exit (<ctrl+x>) the crontab editor.
  126.  
  127. #     Method 2 - (Using LXDE GUI autostart) This should only be used with systems that boot directly into the
  128. #                GUI, otherwise the script won't automatically launch until the GUI is started manually, but
  129. #                it is useful if you boot into the GUI AND want a terminal window open logging the script
  130. #                actions. Note, however, that if you choose this method and you close the terminal window, the
  131. #                script will also exit and will need to be restarted manually to re-enable enforcement.
  132.  
  133. #        8_2a.) The autorun location may be found in a different path on different distributions. This script
  134. #               was developed on Raspbian Stretch, so the paths reflected here are based on that platform. So
  135. #               on a Raspberry Pi running Raspbian Stretch, the path to edit autostart file is used in this
  136. #               example command, and your path may be different. Using a terminal window (if the GUI is loaded)
  137. #               or at a regular CLI terminal, use the following command (substituting your path if neccesary)
  138. #                   $    sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
  139.  
  140. #        8_2b.) Add the following line to the BOTTOM of the autostart file (including quotes.)
  141. #                   lxterminal --command="/usr/local/bin/folder-owner-enforcer"
  142.  
  143. #        8_2c.) Save (<ctrl>+o) and exit (<ctrl>+x) from the nano editor.
  144.    
  145. # 9.) Restart the system. When the system restarts, you can check if the script is running a couple of ways,
  146. #     depending on how you are auto starting it.
  147.  
  148. #     - If you boot straight into the GUI and you configured the LXDE autostart file method, you should see a
  149. #       terminal window open showing the output from the script.
  150.  
  151. #     - If you boot straight into the GUI and you configured the crontab @reboot autostart method, you can click
  152. #       on the task manager and look for the inotifywait instance that should be running.
  153.  
  154. #     - If you boot into the CLI or are connecting remotely through SSH, and are using the crontab @reboot method,
  155. #       you can issue the command "pidof inotifywait" (without the quotes.) If it returns a number, the script is
  156. #       running. You can also use the -viewlog command line option (folder-owner-enforcer -viewlog) to view the
  157. #       current day's log. It should show that the script started up successfully. Note that this method is only
  158. #       really valid on the same day as a system restart, as the log could remain empty for days if nothing has
  159. #       been added or deleted from watched paths.
  160.  
  161. # That's it. You really shouldn't have to touch it again once it's been configured correctly and set to automatically
  162. # start on system restarts. While it is running, any items put into a user's folder will have their ownership set to
  163. # the folder's owner and whatever permission mask you've defined for the script will be applied.
  164.  
  165. # INSTALLATION - END
  166.  
  167. # ==========================================================================================================
  168.  
  169. # USER-DEFINED VARIABLES - START - Adjust these values to configure the script for your setup.
  170.  
  171.     # PATHS
  172.     # Set the base folder. All your USER BASE FOLDERS should be located IN this path.
  173.  
  174.         ROOTPATH="/mnt/studio/shares/sftp"
  175.  
  176.  
  177.     # PERMISSIONS OPTIONS
  178.     # Set the ENABLEMASK value to 1 to apply the USEMASK value to new items. Set to 0 to disable
  179.     # applying the mask. Note that when disabled, only OWNER and GROUP are changed for detected items,
  180.     # so whatever permissions that already exist on the item will remain intact. Note that you can also
  181.     # disable the mask when launching the script by using the "-nomask" command line option. Using the
  182.     # command line option will always take priority over the value set here.
  183.  
  184.         ENABLEMASK=1
  185.  
  186.  
  187.     # Set the default permissions mask you want applied to the new item (file or folder).
  188.     # The default value is 770 (full access for owner and group members, everyone else is denied.)
  189.     # Note that if using the -setmask= option from the command line, the script will use the value that
  190.     # you define at the command line for the mask and not the value set below. Also be aware that if
  191.     # ENABLEMASK is 0 or if the script is called with the -nomask argument, this value isn't enforced.
  192.  
  193.         USEMASK=770
  194.  
  195.  
  196.     # Set PRESERVE to 1 if you wish to preserve existing owners, groups and permissions on existing
  197.     # files and folders in watched folders and only enforce owner, group and permissions on new items.
  198.     # Setting this to 0 (which is the default) will NOT preserve existing owners, groups or permissions
  199.     # and will enforce the ownership, group and permissions (if mask is enabled) on all items, new and
  200.     # existing. Note that defining -preserve at the command line is the same as setting this value to 1.
  201.  
  202.         PRESERVE=0
  203.  
  204.  
  205.     # Set TESTRUN to 1 if you want to test your settings without applying them to the actual folders.
  206.     # Using testrun while configuring the script is a good idea so you can see the folders identified
  207.     # by the script, along with the detected owners and groups. This allows you to view the owners
  208.     # and groups that will be enforced on each respective folder without making any changes before
  209.     # applying enforcement. Note that -testrun can be defined as a command line argument and will
  210.     # override anything defined here, and defining either the -nomask and -setmask options at the
  211.     # command line will also override this setting.
  212.  
  213.         TESTRUN=0
  214.  
  215.  
  216.     # Set the RESTARTDELAY to the value (in seconds) that you want the script to wait before restarting
  217.     # enforcement when a new item is detected in the root folder. This is intended to give the administrator
  218.     # time to configure the owner and group when adding a new user folder before the script restarts the
  219.     # scan and enforcement process. This setting can be overridden by using the command line option
  220.     # -delay=##
  221.     # where ## is the time in seconds.
  222.  
  223.         RESTARTDELAY=60
  224.  
  225.  
  226.     # Set the NOKILL value to enable or disable terminating the inotifywait process. If you are running other
  227.     # instances of inotifywait (outside of this script), the set the NOKILL value to 1 to prevent this script
  228.     # from issuing the "killall inotifywait" command that this script uses to terminate any existing inotifywait
  229.     # processes when initializing and during the process of restarting enforcement to ensure that any abandoned
  230.     # instances are no longer running. If you use inotifywait for monitoring other locations, then this value
  231.     # must be set to 1 to ensure that your other instances remain running. Note that you can also enable nokill
  232.     # by using the -nokill command line option which is the same as setting this value to 1. For all other cases,
  233.     # this should be set to 0.
  234.  
  235.         NOKILL=0
  236.  
  237.  
  238.     # ENABLELOG turns logging on (1) or off (0). LOGFILEPATH Defines the path to store the logfile, DO NOT
  239.     # include a trailing "/". Make sure this path is writeable by the user that runs the script. Change this from
  240.     # /tmp to another folder to prevent logs from being cleared on system restarts.
  241.  
  242.         ENABLELOG=1
  243.         LOGFILEPATH="/tmp"
  244.  
  245.  
  246.   # ADVANCED SETTINGS - These values should not typically need to be touched. They are provided here for advanced
  247.     # configurations such as defining a different system /tmp directory or allowing multiple instances of the script.
  248.  
  249.     # SYS_TMP_PATH=<path> Temp files path (required). This should remain pointed at /tmp on most systems. If you
  250.     # are using a different directory for temporary files on your system, change the path to match your
  251.     # system's /tmp path. Otherwise, leave this value alone. Default value is "/tmp" (including the quotes.)
  252.  
  253.         SYS_TMP_PATH="/tmp"
  254.  
  255.     # ALLOW_MULTIPLE is DISABLED (0) by default. It prevents multiple instances of inotifywait from running by
  256.     # killing any running instances before starting a new instance. If it is ENABLED (1), it will still issue
  257.     # kill commands to PIDs known to the running instance of the script, but will prevent the KILLALL from
  258.     # being issued so other running instances of inotifywait are left alone.
  259.  
  260.         ALLOW_MULTIPLE=0
  261.  
  262.  
  263.     # SHOW_USERS_ON_DELETE is ENABLED (1) by default. It simply adds the currently logged in users to the output
  264.     # log when file deletions are detected in order to identify who was logged in when files were deleted.
  265.     # Note that if you have issues with users being displayed when files are deleted on other non-Debian-based
  266.     # distributions, then you should set this to DISABLED (0).
  267.    
  268.         SHOW_USERS_ON_DELETE=1
  269.        
  270.        
  271. # USER-DEFINED VARIABLES - END - DO NOT MODIFY ANYTHING BELOW THIS LINE IF YOU DON'T KNOW WHAT YOU'RE DOING.
  272.  
  273. # ==========================================================================================================
  274.  
  275. # FUNCTIONS - START
  276.  
  277. # ==========================================================================================================
  278.  
  279. # TIMESTAMP FUNCTION - START
  280. TIMESTAMP()
  281. {
  282.     log_timestamp_date=`date +\%Y-\%m-\%d`
  283.     log_timestamp_hour=`date +\%H`
  284.     log_timestamp_ampm="am"
  285.  
  286.     # Default value when no argument is passed is the same as "nonew". No newline
  287.     # will be sent with the timestamp, so the next echo statement will appear on
  288.     # the same line as the timestamp.
  289.     sendNewLine=0
  290.  
  291.     # Check for passed argument. Passed value can be "newline" or "nonew" (default)
  292.     if [ ! -z $1 ]; then
  293.         # Argument passed, so test it.
  294.         case $1 in
  295.             "newline")
  296.                 sendNewLine=1
  297.             ;;
  298.             "nonew")
  299.                 sendNewLine=0
  300.             ;;
  301.         esac
  302.     fi
  303.  
  304.     if [ $log_timestamp_hour -gt 11 ]; then
  305.         log_timestamp_hour=$(($log_timestamp_hour-12))
  306.         log_timestamp_ampm="pm"
  307.     fi
  308.  
  309.     if [ $log_timestamp_hour -eq 0 ]; then
  310.         log_timestamp_hour=12
  311.     fi
  312.  
  313.     if [ $sendNewLine -eq 1 ]; then
  314.         # Send with a newline character. The next echo will appear on a new line.
  315.         log_timestamp="${log_timestamp_date} ${log_timestamp_hour}:`date +\%M:\%S` ${log_timestamp_ampm}"
  316.         echo -e "\e[96m\e[1m${log_timestamp}\e[0m" 2>&1 | tee -a $TMPLOG
  317.     else
  318.         # Don't send a newline character. Keep next echo on the same line as the timestamp.
  319.         log_timestamp="${log_timestamp_date} ${log_timestamp_hour}:`date +\%M:\%S` ${log_timestamp_ampm}: "
  320.         echo -n -e "\e[96m\e[1m${log_timestamp}\e[0m" 2>&1 | tee -a $TMPLOG
  321.     fi
  322. }
  323. # TIMESTAMP FUNCTION - END
  324.  
  325. # ==========================================================================================================
  326.  
  327. # VALIDATEMASK FUNCTION - START
  328. VALIDATEMASK()
  329. {
  330.     maskVal="$USEMASK"
  331.     checkFirstChar=${maskVal::1}
  332.     checkSecondChar=${maskVal:1:1}
  333.  
  334.     case "$checkFirstChar" in
  335.         "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7")
  336.             # Since the first character was a valid number, make sure the second character is too
  337.             case $checkSecondChar in
  338.                 "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7")
  339.                     VALIDMASK=1
  340.                 ;;
  341.                 *)
  342.                     # The second character was NOT a valid number. Trigger error.
  343.                     echo -e "\e[91m\e[1mERROR!\e[0m Invalid mask was specified. Number [0-7] was expected." 2>&1 | tee -a $TMPLOG
  344.                     echo "$SCRIPT_VER has terminated." 2>&1 | tee -a $TMPLOG
  345.                     LOG_CLEAN_OUTPUT
  346.                     exit 1;
  347.                 ;;
  348.             esac
  349.         ;;
  350.  
  351.         "-"|"+")
  352.             # Since the first character was a valid symbol, make sure the second character is also valid
  353.             case $checkSecondChar in
  354.                 "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"r"|"w"|"x")
  355.                     VALIDMASK=1
  356.                 ;;
  357.                 *)
  358.                     # The second character was NOT valid. Trigger error.
  359.                     echo -e "\e[91m\e[1mERROR!\e[0m Invalid mask was specified. When using + or - for the mask, the" 2>&1 | tee -a $TMPLOG
  360.                     echo "next expected character should have been a number [0-7] or a letter [r] [w] or [x]." 2>&1 | tee -a $TMPLOG
  361.                     echo "$SCRIPT_VER has terminated." 2>&1 | tee -a $TMPLOG
  362.                     LOG_CLEAN_OUTPUT
  363.                     exit 1;
  364.                 ;;
  365.             esac
  366.         ;;
  367.  
  368.         "a"|"o"|"g"|"u")
  369.             if [[ $checkSecondChar == "=" ]]; then
  370.                 VALIDMASK=1
  371.             else
  372.                 echo -e "\e[91m\e[1mERROR!\e[0m Invalid mask was specified. Equal sign expected." 2>&1 | tee -a $TMPLOG
  373.                 echo "$SCRIPT_VER has terminated." 2>&1 | tee -a $TMPLOG
  374.                 LOG_CLEAN_OUTPUT
  375.                 exit 1;
  376.             fi
  377.         ;;
  378.  
  379.         *)
  380.             # The first character of the second argument was NOT a valid mask character. Trigger error.
  381.             echo -e "\e[91m\e[1mERROR!\e[0m Invalid mask was specified." 2>&1 | tee -a $TMPLOG
  382.             echo "$SCRIPT_VER has terminated." 2>&1 | tee -a $TMPLOG
  383.             LOG_CLEAN_OUTPUT
  384.             exit 1;
  385.         ;;
  386.     esac
  387.     LOG_CLEAN_OUTPUT
  388. }
  389. # VALIDATEMASK FUNCTION - END
  390.  
  391. # ==========================================================================================================
  392.  
  393. # SCANFOLDERS FUNCTION - START
  394. SCANFOLDERS()
  395. {
  396.     # SCANFOLDERS DETERMINES ENFORCEMENT VALUES - START - Cycle through the user folders in the ROOTPATH
  397.     #               to identify the paths that will be watched by inotify, and retrieve owner and group
  398.     #               information for each user folder to apply to any new (and existing) items in each user's folder.
  399.  
  400.     # INITIALIZE ARRAYS
  401.     DIRPATH=()
  402.     DIROWNER=()
  403.     DIRGROUP=()
  404.  
  405.     # IDENTIFY USER FOLDERS - Identify folders IN the defined ROOTPATH variable, getting their name, owner and group, and assign each an id.
  406.     echo -e "\e[96m\e[1m=======================================================================\e[0m" 2>&1 | tee -a $TMPLOG
  407.     echo -e "\e[96m\e[1m$SCRIPT_VER - Folder Ownership Scan\e[0m" 2>&1 | tee -a $TMPLOG
  408.     echo -e "\e[96m\e[1m=======================================================================\e[0m" 2>&1 | tee -a $TMPLOG
  409.  
  410.     DIRID=1
  411.  
  412.     for FOLDER in $ROOTPATH
  413.     do
  414.         if [[ -d "$FOLDER" && ! -L "$FOLDER" ]]; then
  415.             tmpPath="${FOLDER}"
  416.             TIMESTAMP newline
  417.             echo -e "\e[34m\e[1mIdentified Folder for Enforcement:\e[0m" 2>&1 | tee -a $TMPLOG
  418.             echo -e "  \e[34m\e[1m$tmpPath\e[0m" 2>&1 | tee -a $TMPLOG
  419.             tmpUser=`stat -c "%U" "$tmpPath"`
  420.             tmpGroup=`stat -c "%G" "$tmpPath"`
  421.  
  422.             DIRPATH[$DIRID]=$tmpPath
  423.             DIROWNER[$DIRID]=$tmpUser
  424.             DIRGROUP[$DIRID]=$tmpGroup
  425.  
  426.             echo -e "\e[1mRetrieving and storing owner information\e[0m" 2>&1 | tee -a $TMPLOG
  427.             echo -e "    Folder Record ID: \e[1m $DIRID\e[0m" 2>&1 | tee -a $TMPLOG
  428.             echo -e "    Enforcement Path: \e[34m\e[1m${DIRPATH[$DIRID]}\e[0m" 2>&1 | tee -a $TMPLOG
  429.             echo -e "    Identified Owner: \e[35m\e[1m${DIROWNER[$DIRID]}\e[0m" 2>&1 | tee -a $TMPLOG
  430.             echo -e "    Identified Group: \e[104m\e[1m${DIRGROUP[$DIRID]}\e[0m" 2>&1 | tee -a $TMPLOG
  431.  
  432.             # ASSIGN THE FOLDER OWNER AND GROUP TO ALL ITEMS IN THE CURRENT FOLDER RECURSIVELY
  433.             # This is to ensure that existing files and folders in each user's directory have the correct owner
  434.             # group and permissions enforced.
  435.  
  436.             if [ $TESTRUN -eq 1 ]; then
  437.                 # This is a Test Run so do not enforce anything
  438.                 echo -e "\e[42m\e[1mTest Run\e[0m" 2>&1 | tee -a $TMPLOG
  439.                 echo "ownership and group information is not being enforced. If enforcement" 2>&1 | tee -a $TMPLOG
  440.                 echo "were enabled, all existing items and any new items added to" 2>&1 | tee -a $TMPLOG
  441.                 echo -e "\e[34m\e[1m${DIRPATH[$DIRID]}\e[0m" 2>&1 | tee -a $TMPLOG
  442.                 echo -e "would have \e[35m\e[1m${DIROWNER[$DIRID]}\e[0m:\e[104m\e[1m${DIRGROUP[$DIRID]}\e[0m" 2>&1 | tee -a $TMPLOG
  443.                 echo "enforced as owner and group if this were not a test run." 2>&1 | tee -a $TMPLOG
  444.             else
  445.                 # This is NOT a Test Run - Enforce based on settings
  446.                 if [ $PRESERVE -eq 1 ]; then
  447.                     # Not a test run but preserve is on, so enforce ownership and group only on new files
  448.                     echo -e "Enforcing owner and group only on new items in:" 2>&1 | tee -a $TMPLOG
  449.                     echo -e "  \e[34m\e[1m${DIRPATH[$DIRID]}\e[0m" 2>&1 | tee -a $TMPLOG
  450.                 else
  451.                     # Not a test run and preserve is off so enforce ownership and group on existing files
  452.                     echo "Enforcing owner and group on existing items in:" 2>&1 | tee -a $TMPLOG
  453.                     echo -e "  \e[34m\e[1m${DIRPATH[$DIRID]}\e[0m" 2>&1 | tee -a $TMPLOG
  454.                 fi
  455.  
  456.                 updMask=0
  457.  
  458.                 if [ $PRESERVE -eq 0 ]; then
  459.                     # PRESERVE is off, so enforce owner and group on existing items in detected folder.
  460.                     sudo chown -R "${DIROWNER[$DIRID]}":"${DIRGROUP[$DIRID]}" "${DIRPATH[$DIRID]}"
  461.                     if [ $? -ne 0 ]; then
  462.                         # ERROR SETTING OWNER - GROUP
  463.                         echo -e "\e[91m\e[1mERROR!\e[0m Unable to set ownership and group to one or more items in:" 2>&1 | tee -a $TMPLOG
  464.                         echo ${DIRPATH[$DIRID]}" 2>&1 | tee -a $TMPLOG
  465.  
  466.                     else
  467.                         # OWNER AND GROUP WERE SET SUCCESSFULLY
  468.                         echo -e "  \e[32m\e[1mSuccess!\e[0m Owner and group have been changed to:" 2>&1 | tee -a $TMPLOG
  469.                         echo -e "    \e[35m\e[1m${DIROWNER[$DIRID]}\e[0m:\e[104m\e[1m${DIRGROUP[$DIRID]}\e[0m" 2>&1 | tee -a $TMPLOG
  470.  
  471.                         # Since owner and group were changed successfully, update permissions mask
  472.                         updMask=1
  473.                     fi
  474.  
  475.                     # If the owner and group were successfully changed AND $ENABLEMASK is 'on' (1)
  476.                     if [[ $updMask -eq 1 && $ENABLEMASK -eq 1  ]]; then
  477.                         echo -e "Enforcing \e[7m$USEMASK\e[0m permissions on all items in:" 2>&1 | tee -a $TMPLOG
  478.                         echo -e "  \e[34m\e[1m${DIRPATH[$DIRID]}\e[0m" 2>&1 | tee -a $TMPLOG
  479.  
  480.                         sudo chmod "$USEMASK" -R "${DIRPATH[$DIRID]}"
  481.                         if [ $? -ne 0 ]; then
  482.                             # ERROR SETTING PERMISSIONS MASK
  483.                             echo -e "\e[91m\e[1mERROR!\e[0m Unable to set permissions on one or more items in" 2>&1 | tee -a $TMPLOG
  484.                             echo "  ${DIRPATH[$DIRID]}" 2>&1 | tee -a $TMPLOG
  485.                             echo "" 2>&1 | tee -a $TMPLOG
  486.                             echo -e "\e[34m-------------------------------------------------------------\e[0m" 2>&1 | tee -a $TMPLOG
  487.                         else
  488.                             # PERMISSIONS SET SUCCESSFULLY
  489.                             echo -e "  \e[32m\e[1mSuccess!\e[0m Enforced \e[7m$USEMASK\e[0m on ALL items in" 2>&1 | tee -a $TMPLOG
  490.                             echo -e "    \e[34m\e[1m${DIRPATH[$DIRID]}\e[0m" 2>&1 | tee -a $TMPLOG
  491.                             echo "" 2>&1 | tee -a $TMPLOG
  492.                             echo -e "\e[34m-------------------------------------------------------------\e[0m" 2>&1 | tee -a $TMPLOG
  493.                             # RESET updMask to 0 for next job
  494.                             updMask=0
  495.                         fi
  496.  
  497.                     else
  498.                         # old elif [[ $updMask -eq 1 && $ENABLEMASK -eq 0 ]]; then
  499.                         echo "Permission masks are disabled. Permissions will not be changed." 2>&1 | tee -a $TMPLOG
  500.                     fi
  501.  
  502.                 else
  503.                     # Preserve flag enabled - do not enforce rules on existing items.
  504.                     echo -e "\e[42m\e[1mPreserve Mode\e[0m Preserve is enabled. Enforcement will only apply" 2>&1 | tee -a $TMPLOG
  505.                     echo "to new items. Owner, group and permissions on existing items will" 2>&1 | tee -a $TMPLOG
  506.                     echo "be preserved." 2>&1 | tee -a $TMPLOG
  507.                 fi
  508.                 # End preserve
  509.             fi
  510.             # End testrun if
  511.  
  512.             # Increment DIRID for the next record.
  513.             DIRID=$((DIRID+1))
  514.         fi
  515.     done
  516.     LOG_CLEAN_OUTPUT
  517. }
  518. # SCANFOLDERS FUNCTION - END
  519.  
  520. # ==========================================================================================================
  521.  
  522. # ENFORCEMENT FUNCTION - START
  523. ENFORCEMENT()
  524. {
  525.     # Begin monitoring BASEPATH (add a trailing slash) folder recursively. React to close_write or moved_to events.
  526.     echo -e "\e[96m\e[1m=======================================================================\e[0m" 2>&1 | tee -a $TMPLOG
  527.     TIMESTAMP newline
  528.     echo -e "\e[96m\e[1m$SCRIPT_VER - Enforcement Started\e[0m" 2>&1 | tee -a $TMPLOG
  529.     echo -e "\e[96m\e[1m=======================================================================\e[0m" 2>&1 | tee -a $TMPLOG
  530.     LOG_CLEAN_OUTPUT
  531.  
  532.     inotifywait -e create,delete -r -m --format "%e %w%f" "${BASEPATH}"/ |
  533.     while read trgEvent updItem;
  534.     do
  535.         echo -e "\e[34m-------------------------------------------------------------\e[0m" 2>&1 | tee -a $TMPLOG
  536.         TIMESTAMP newline
  537.  
  538.         case $trgEvent in
  539.         # DELETE DETECTED - START
  540.         DELETE|DELETE*)
  541.         echo -e "\e[31m\e[1mDeletion detected:\e[0m" 2>&1 | tee -a $TMPLOG
  542.         echo -e "    \e[34m\e[1m$updItem\e[0m" 2>&1 | tee -a $TMPLOG
  543.         if [ $SHOW_USERS_ON_DELETE -eq 1 ]; then
  544.             # SHOW_USERS_ON_DELETE is enabled, so print currently connected users.
  545.             curUsers=$( ps -ef | grep 'shd' | grep -v ^root | grep -v notty | awk '{ print $1 }' | tr '\n' ';' )
  546.             echo -e -n "\e[96m\e[1mCurrent Users: " 2>&1 | tee -a $TMPLOG
  547.             echo -e "\e[21m${curUsers}\e[0m" 2>&1 | tee -a $TMPLOG
  548.         fi
  549.         ;;
  550.         # DELETE DETECTED - END
  551.  
  552.         # CREATE DETECTED - START
  553.         CREATE|CREATE*)
  554.         echo -e "\e[96m\e[1mNew item detected:\e[0m" 2>&1 | tee -a $TMPLOG
  555.         echo -e "  \e[34m\e[1m $updItem\e[0m" 2>&1 | tee -a $TMPLOG
  556.  
  557.         # Cycle through known monitored folders to determine which known path matches
  558.         # the base path that the updItem was created or moved to.
  559.  
  560.         DIRCT=${#DIRPATH[@]}
  561.         DIRID=1
  562.         isBasePath=0
  563.         ownerFound=0
  564.  
  565.         echo -e "Owner and Group Enforcement:" 2>&1 | tee -a $TMPLOG
  566.  
  567.         while [[ $DIRID -le $DIRCT && $ownerFound -lt 1 ]]
  568.         do
  569.             # updItemPath is the full path with everything to the right of the last slash stripped out
  570.             # so it can be compared to the known BASEPATH to so we can make sure the new item was not
  571.             # created in the root folder.
  572.             updItemPath=${updItem%/*}
  573.             if [[ "$updItemPath" == "$BASEPATH" ]]; then
  574.                 # The new item was created in the base (root) path. We will not change anything that is
  575.                 # created directly in the root of the user tree.
  576.                 echo "Item was created in the root path. $SCRIPT_VER does" 2>&1 | tee -a $TMPLOG
  577.                 echo "not enforce items created in or added to the root path." 2>&1 | tee -a $TMPLOG
  578.  
  579.                 # Check if new item is a file or a folder. If it is a folder, enforcement will need to
  580.                 # be restarted in order to know the owner and group to be assigned to any items that
  581.                 # are created in the new folder. If it is a file, don't do anything as the message
  582.                 # above covers the fact that the item will not have ownership or group enforced.
  583.                 if [[ -f "${updItem}" ]]; then
  584.                     echo -e "\e[34m\e[1m${updItem}\e[0m is a \e[1mfile\e[0m." 2>&1 | tee -a $TMPLOG
  585.                     echo -e "Enforcement does \e[1mnot\e[0m need to be restarted." 2>&1 | tee -a $TMPLOG
  586.                     isBasePath=1
  587.                     ownerFound=1
  588.  
  589.                 else
  590.                     if [[ -d "${updItem}" ]]; then
  591.                         echo -e "\e[34m\e[1m${updItem}\e[0m is a \e[1mfolder\e[0m." 2>&1 | tee -a $TMPLOG
  592.                         echo -e "\e[96m$SCRIPT_VER\e[0m needs to be restarted to establish" 2>&1 | tee -a $TMPLOG
  593.                         echo "enforcement on:" 2>&1 | tee -a $TMPLOG
  594.                         echo -e "  \e[34m\e[1m$updItem\e[0m" 2>&1 | tee -a $TMPLOG
  595.                         isBasePath=1
  596.                         ownerFound=1
  597.                         LOG_CLEAN_OUTPUT
  598.                         RESTART_ENFORCE
  599.                     fi
  600.                 fi
  601.             fi
  602.  
  603.             if [[ "${updItem}" == *"${DIRPATH[$DIRID]}"* && $isBasePath -eq 0 ]]; then
  604.                 curID=$DIRID
  605.  
  606.                 # ASSIGN OWNER GROUP - START
  607.                 # Assign the owner and group of the updItem to the owner and group of the folder
  608.                 # it was created in or moved to.
  609.                 # The wasUpdated flag values: 0=Not Updated, 1=Update Failed (Max retries), 2=Success
  610.                 wasUpdated=0
  611.                 curRetry=0
  612.                 maxRetries=5
  613.                 while [ $wasUpdated -lt 1 ]
  614.                 do
  615.                     sudo chown "${DIROWNER[$curID]}":"${DIRGROUP[$curID]}" "${updItem}"
  616.                     if [ $? -ne 0 ]; then
  617.  
  618.                         case $curRetry in
  619.                             0|1)
  620.                             echo -n -e "\e[97m\e[1mERROR!\e[0m " 2>&1 | tee -a $TMPLOG
  621.                             ;;
  622.                             2|3)
  623.                             echo -n -e "\e[93m\e[1mERROR!\e[0m " 2>&1 | tee -a $TMPLOG
  624.                             ;;
  625.                             4|5)
  626.                             echo -n -e "\e[91m\e[1mERROR!\e[0m " 2>&1 | tee -a $TMPLOG
  627.                             ;;
  628.                         esac
  629.  
  630.                         echo "Unable to change ownership of ${updItem}." 2>&1 | tee -a $TMPLOG
  631.                         curRetry=$((curRetry+1))
  632.  
  633.                         case $curRetry in
  634.                             1)
  635.                                 # Workaround for issue where new folders that have no spaces in their name have
  636.                                 # whitespace added to the end of the variable when it is read by the script making,
  637.                                 # it impossible to set the ownership and permissions. This workaround will try
  638.                                 # removing the last character, which should be whitespace, then try again.
  639.                                 echo "Attempting workaround for known whitespace issue and retrying." 2>&1 | tee -a $TMPLOG
  640.                                 tmpItem="$updItem"
  641.                                 updItem=${updItem%?};
  642.                             ;;
  643.  
  644.                             2)
  645.                                 # The fix for the known whitespace issue did not work. Reset the variable back
  646.                                 # to its original value for additional retries in case the file was locked.
  647.                                 $updItem="$tmpItem"
  648.                                 sleep 1s
  649.                             ;;
  650.                         esac
  651.  
  652.                         if [ $curRetry -ge $maxRetries ]; then
  653.                             echo -e "\e[91m\e[1mERROR!\e[0m Maximum retry limit reached. Ownership of" 2>&1 | tee -a $TMPLOG
  654.                             echo -e "\e[34m\e[1m${updItem}\e[0m has \e[1mNOT\e[0m been changed." 2>&1 | tee -a $TMPLOG
  655.                             # Set the wasUpdated flag to 1 to prevent the loop from executing again.
  656.                             wasUpdated=1
  657.                         fi
  658.  
  659.                     else
  660.                         echo -e "  \e[32m\e[1mSuccess!\e[0m Enforced owner: \e[35m\e[1m${DIROWNER[$curID]}\e[0m, group: \e[104m\e[1m${DIRGROUP[$curID]}\e[0m." 2>&1 | tee -a $TMPLOG
  661.                         # Update was successful so change the wasUpdated flag to 2 to prevent executing again
  662.                         # and sets the flag to run the permissions mask on the new item and set the ownerFound
  663.                         # flag to 1 to indicate the correct owner and group have been identified and applied.
  664.                         wasUpdated=2
  665.                         ownerFound=1
  666.                     fi
  667.  
  668.                     if [[ $wasUpdated -eq 2 && $ENABLEMASK -eq 1 && $isBasePath -eq 0 ]]; then
  669.                         # Ownership and group were successfully changed, and enable mask is turned on, so set permissions
  670.                         # if the item wasn't created in the base (root) path
  671.                         echo "Permissions Enforcement" 2>&1 | tee -a $TMPLOG
  672.                         sudo chmod "$USEMASK" "${updItem}" 2>&1 | tee -a $TMPLOG
  673.  
  674.                         if [ $? -ne 0 ]; then
  675.                             echo -e "\e[91m\e[1mERROR!\e[0m Failed to set permissions on:" 2>&1 | tee -a $TMPLOG
  676.                             echo -e "  \e[34m\e[1m${updItem}\e[0m." 2>&1 | tee -a $TMPLOG
  677.                         else
  678.                             echo -e "  \e[32m\e[1mSuccess!\e[0m Permissions set to \e[7m${USEMASK}\e[0m." 2>&1 | tee -a $TMPLOG
  679.                         fi
  680.                     fi
  681.                 done
  682.                 # ASSIGN OWNER GROUP - END
  683.             fi
  684.  
  685.             # If the owner was identified, set the DIRID to the DIRCT VALUE+1 to stop script from searching other paths
  686.             if [ $ownerFound -eq 1 ]; then
  687.                 DIRID=$((DIRCT+1))
  688.             fi
  689.  
  690.             # Increase the DIRID by 1 to check the next record. If the owner was already found, it will cause the DIRID
  691.             # to be a value of 2 higher than the DIRCT value, ensuring the loop stops when the owner is identified.
  692.             DIRID=$((DIRID+1))
  693.             isBasePath=0
  694.         done
  695.         ;;
  696.         # CREATE DETECTED - END
  697.        
  698.         esac
  699.         LOG_CLEAN_OUTPUT
  700.  
  701.     done
  702. }
  703. # ENFORCEMENT FUNCTION - END
  704.  
  705. # ==========================================================================================================
  706.  
  707. # RESTART ENFORCEMENT FUNCTION - START
  708. RESTART_ENFORCE()
  709. {
  710.     # Check the NOKILL option before restarting.
  711.     if [[ $NOKILL -lt 1 ]]; then
  712.         # NOKILL is NOT active, so restart
  713.         echo -e "\e[34m-------------------------------------------------------------\e[0m" 2>&1 | tee -a $TMPLOG
  714.         TIMESTAMP newline
  715.         echo -e "\e[96m\e[1m$SCRIPT_VER will restart enforcement in $RESTARTDELAY seconds.\e[0m" 2>&1 | tee -a $TMPLOG
  716.         sleep "${RESTARTDELAY}"s
  717.         echo -e "\e[34m-------------------------------------------------------------\e[0m" 2>&1 | tee -a $TMPLOG
  718.         TIMESTAMP
  719.         echo -e "\e[96m\e[1mRestarting enforcement now.\e[0m" 2>&1 | tee -a $TMPLOG
  720.  
  721.         # Call the KILL_INOTIFY function to close any old running script and inotifywait instances
  722.         KILL_INOTIFY
  723.  
  724.         # Rescan folders for new user folder to enforce then restart enforcement
  725.         SCANFOLDERS
  726.         ENFORCEMENT
  727.     else
  728.         echo -e "The \e[42m\e[1m-nokill\e[0m option was specified, which prevents" 2>&1 | tee -a $TMPLOG
  729.         echo "killing any running processes. This prevents the script from" 2>&1 | tee -a $TMPLOG
  730.         echo "properly restarting internal functions automatically, which is" 2>&1 | tee -a $TMPLOG
  731.         echo "required to establish enforcement on new items. Please exit and" 2>&1 | tee -a $TMPLOG
  732.         echo "restart the script to manually enable enforcement on new items" 2>&1 | tee -a $TMPLOG
  733.         echo "created in the root of the user tree." 2>&1 | tee -a $TMPLOG
  734.     fi
  735.     LOG_CLEAN_OUTPUT
  736.  
  737. }
  738. # RESTART ENFORCEMENT FUNCTION - END
  739.  
  740. # ==========================================================================================================
  741.  
  742. # KILL_INOTIFY FUNCTION - START
  743. KILL_INOTIFY()
  744. {
  745. # NOKILL CHECK - START
  746.     if [[ $NOKILL -lt 1 && $TESTRUN -ne 1 ]]; then
  747.         # NOKILL is NOT ENABLED and NOT A TEST RUN - So issue KILL command(s) if needed
  748.         echo -e "\e[93m=======================================================================\e[0m" 2>&1 | tee -a $TMPLOG
  749.         echo -e "\e[93m\e[1m$SCRIPT_VER - Running Instances Check\e[0m" 2>&1 | tee -a $TMPLOG      
  750.         echo -e "\e[93m=======================================================================\e[0m" 2>&1 | tee -a $TMPLOG
  751.         TIMESTAMP newline
  752.         echo -e "\e[93mChecking for previous running instances of the script.\e[0m" 2>&1 | tee -a $TMPLOG
  753.  
  754.         # $PPID - Parent Process ID, $$ - Process ID, $! - Last background task Process ID
  755.         curPID=$$
  756.  
  757.         # PID Log paths - Used to store PIDs of script instances to try and clean up
  758.         # any left-behind processes from previous or existing runs so that (hopefully)
  759.         # only one instance of the script remains active.
  760.         logPath_CurPID="${SYS_TMP_PATH}/.${MYNAME}_ppid_cur"
  761.         logPath_OldPID="${SYS_TMP_PATH}/.${MYNAME}_ppid_old"
  762.  
  763.         # Define local variables
  764.         logRead_CurPID=""
  765.         logRead_OldPID=""
  766.         oldPid_Parent=""
  767.  
  768.         kill_PID_old=0
  769.         kill_Error=0
  770.  
  771.         # PPID CHECK - START
  772.         if [ ! -f "${logPath_CurPID}" ]; then
  773.             # no existing ppid log exists, so store the current id in the file
  774.             echo "${curPID}" > "${logPath_CurPID}"
  775.         else
  776.             # ppid log file exists, check that the value in the log file matches the ppid of the current instance of the script.
  777.             logRead_CurPID=$( cat "$logPath_CurPID" )
  778.  
  779.             # Current PID matches the Current PID Identified in the current PID log
  780.             if [ $curPID -eq $logRead_CurPID ]; then
  781.                 kill_PID_old=0
  782.                 echo -e "\e[93mOnly the current script instance PID was found.\e[0m" 2>&1 | tee -a $TMPLOG
  783.                 echo -e "\e[93mAttempting to kill running inotifywait instance(s).\e[0m" 2>&1 | tee -a $TMPLOG
  784.             else
  785.                 # current log file ppid does NOT match the ppid of the current script instance
  786.                 # copy the existing current ppid log into the old ppid log then replace the
  787.                 # PID in the current ppid log
  788.                 echo "${logRead_CurPID}" >> "${logPath_OldPID}"
  789.                 echo "${curPID}" > "${logPath_CurPID}"
  790.                 # Set the flag to trigger the kill old pids since we know at least one old pid exists to check for
  791.                 kill_PID_old=1
  792.             fi
  793.  
  794.             # kill_PID_old ENABLED - START
  795.             if [ $kill_PID_old -eq 1 ]; then
  796.  
  797.                 # LOOP THROUGH OLD PIDs - START
  798.                 echo -e "\e[93mCycling through known previous PIDs.\e[0m" 2>&1 | tee -a $TMPLOG
  799.                 while read line
  800.                     do
  801.                         logRead_OldPID=($line)
  802.                         echo -e "\e[93mPID Found: \e[1m$logRead_OldPID\e[0m" 2>&1 | tee -a $TMPLOG
  803.  
  804.                         # KILL OLD PPID - START
  805.                         # check if the old PPID is still running by requesting its parent process
  806.                         oldPid_Parent=$( ps -o ppid= "$logRead_OldPID" )
  807.  
  808.                         if [ ! -z "${oldPid_Parent}" ]; then
  809.                         # oldPid_Parent was NOT empty, so the old process is still running as a parent was able to be identified
  810.                             if [ $DEBUG -eq 1 ]; then echo -e "\e[45m\e[1mDEBUG:\e[0mThe value of oldPid_Parent is: ${oldPid_Parent}"; fi
  811.  
  812.                             echo -e "\e[93mA previous instance is still running \e[1m(${logRead_OldPID})\e[0m\e[93m.\e[0m" 2>&1 | tee -a $TMPLOG
  813.                             echo -e "\e[93mAttempting to terminate process \e[1m(${logRead_OldPID})\e[0m\e[93m.\e[0m" 2>&1 | tee -a $TMPLOG
  814.  
  815.                             kill $logRead_OldPID
  816.  
  817.                             if [ $? -eq 0 ]; then
  818.                                 echo  -e "\e[93mSuccessfully terminated process \e[1m(${logRead_OldPID})\e[0m\e[1m.\e[0m" 2>&1 | tee -a $TMPLOG
  819.                                 echo -e "\e[93mGiving system time to terminate related inotifywait instances."
  820.                                 sleep 5s
  821.                             else
  822.                                 echo -e "\e[91m\e[1mERROR!\e[0m \e[93mScript was unable to terminate process \e[1m(${logRead_OldPID})\e[0m\e[93m.\e[0m" 2>&1 | tee -a $TMPLOG
  823.                                 kill_Error=1
  824.                             fi
  825.  
  826.                         else
  827.                         # The old PPID is NOT running
  828.                             echo  -e "\e[93mThe previous process \e[1m(${logRead_OldPID})\e[0m\e[93m is not running.\e[0m" 2>&1 | tee -a $TMPLOG
  829.                         fi
  830.                         # KILL OLD PPID - END
  831.  
  832.                     done < $logPath_OldPID
  833.                     # LOOP THROUGH OLD PIDs - START
  834.  
  835.                     # Finished looping through old script PIDs and killing them
  836.                     # REMOVE OLD PPID LOG
  837.                     if [ $kill_Error -ne 1 ]; then
  838.                     # Killed all known old processes so remove the old pid log file
  839.                         sudo rm $logPath_OldPID
  840.                     else
  841.                     # One or more processes were not killed. Do NOT delete the old pid log file
  842.                         echo -e "\e[93mThis is not a fatal error so continuing enforcement. Be aware\e[0m" 2>&1 | tee -a $TMPLOG
  843.                         echo -e "\e[93mthat if the process(es) that were not able to be stopped are\e[0m" 2>&1 | tee -a $TMPLOG
  844.                         echo -e "\e[93mstill running and may need a full system reboot to clear.\e[0m" 2>&1 | tee -a $TMPLOG
  845.                     fi
  846.  
  847.             # else
  848.                 # Old PPID is not active
  849.             fi
  850.             # kill_PID_old ENABLED - END
  851.         fi
  852.         # PPID CHECK - END
  853.  
  854.         if [ $ALLOW_MULTIPLE -eq 0 ]; then
  855.             # ALLOW_MULTIPLE is DISABLED (0) so kill other inotifywait instances
  856.             # Check for unknown instances of inotifywait. If any still exist, send kill command
  857.             checkInotifyUnknown=$(pgrep inotifywait)
  858.             if [ ! -z $checkInotifyUnknown ]; then
  859.                 # Unknown inotifywatch processes were found running. May be orphans so use killall
  860.                 echo -e "\e[93mOne or more inotifywait processes are still running. Attempting\e[0m" 2>&1 | tee -a $TMPLOG
  861.                 echo -e "\e[93mto stop by sending a killall to try and clean these up as they are\e[0m" 2>&1 | tee -a $TMPLOG
  862.                 echo -e "\e[93mlikely either orphans or were launched from the currently running\e[0m" 2>&1 | tee -a $TMPLOG
  863.                 echo -e "\e[93mscript instance.\e[0m" 2>&1 | tee -a $TMPLOG
  864.                 killall -9 inotifywait
  865.                 if [ $? -ne 0 ]; then
  866.                     TIMESTAMP newline
  867.                     echo -e "\e[91m\e[1mERROR!\e[0m \e[93mFailed to kill one or more running inotifywait processes.\e[0m" 2>&1 | tee -a $TMPLOG
  868.                     echo -e "\e[93mIdentified PID(s):\e[0m" 2>&1 | tee -a $TMPLOG
  869.                     echo $checkInotifyUnknown 2>&1 | tee -a $TMPLOG
  870.                     echo -e "\e[93mAttempt to manually kill each process identified. If the kill command\e[0m" 2>&1 | tee -a $TMPLOG
  871.                     echo -e "\e[93mcontinues to fail, you should restart the system.\e[0m" 2>&1 | tee -a $TMPLOG
  872.                 else
  873.                     # All identified unknown inotifywait instances were killed
  874.                     echo -e "\e[93mSuccessfully stopped all identified inotifywait processes.\e[0m" 2>&1 | tee -a $TMPLOG
  875.                 fi
  876.  
  877.             else
  878.                 # No running inotifywait processes were found running.
  879.                 echo -e "\e[93mNo inotifywait processes were found running.\e[0m" 2>&1 | tee -a $TMPLOG
  880.  
  881.             fi
  882.         else
  883.             # ALLOW_MULTIPLE is ENABLED (1), so do NOT kill other inotifywait
  884.             echo -e "\e[93m\e[1mALLOW MULTIPLE\e[21m is \e[1mENABLED\e[21m.\e[0m"
  885.             echo -e "\e[93mUnknown inotifywait processes will \e[1mNOT\e[21m be stopped.\e[0m" 2>&1 | tee -a $TMPLOG
  886.         fi
  887.  
  888.     else
  889.         # NOKILL is ENABLED or TESTRUN is ON - So DO NOT ISSUE KILL Commands
  890.  
  891.         if [ $NOKILL -eq 1 ]; then
  892.             echo -e "\e[93m\e[1mNOKILL\e[0m\e[93m is enabled. Kill commands were \e[1mNOT\e[21m issued.\e[0m"
  893.         fi
  894.  
  895.         if [ $TESTRUN -eq 1 ]; then
  896.             echo -e "\e[93m\e[1mTEST RUN\e[0m\e[93m - Since this is a test run, kill commands were\e[0m"
  897.             echo -e "\e[93mNOT issued.\e[0m"
  898.         fi
  899.  
  900.     fi
  901. # NOKILL CHECK - END
  902.  
  903.     LOG_CLEAN_OUTPUT
  904. }
  905. # KILL_INOTIFY FUNCTION - END
  906.  
  907. # ==========================================================================================================
  908.  
  909. # LOG_CLEAN_OUTPUT FUNCTION - START - The purpose of this function is to clean up the formatting escape sequences
  910. #                                     from the log file. When triggered, it exports the temporary logfile into the
  911. #                                     current day's log file, cleaning up the output.
  912.  
  913. LOG_CLEAN_OUTPUT()
  914. {
  915.     if [ $ENABLELOG -eq 1 ]; then
  916.         # Logging is enabled
  917.         # Write temporary log data to daily log, removing text formatting escape sequences
  918.         LOGFILE="${LOGFILEPATH}/${MYNAME}_`date +\%Y\%m\%d`.log"
  919.  
  920.         if [ -f $TMPLOG ]; then
  921.             # TMPLOG Exists so clean up output and write it to the main log
  922.             cat $TMPLOG | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,3})?)?[m|K]//g" >> $LOGFILE
  923.             if [ $? -eq 0 ]; then
  924.                 # Successfully flushed TMPLOG data to main LOGFILE so delete TMPLOG to clear it
  925.                 sudo rm $TMPLOG
  926.             #else
  927.             fi
  928.         # else
  929.             # TMPLOG doesn't exist, so there's nothing to write to the main log
  930.         fi
  931.  
  932.     # else
  933.         # Logging is disabled, so no need to touch any files as log output was redirected to /dev/null.
  934.     fi
  935. }
  936. # LOG_CLEAN_OUTPUT FUNCTION - END
  937.  
  938. # ==========================================================================================================
  939.  
  940. # FUNCTIONS - END
  941.  
  942. # ==========================================================================================================
  943.  
  944. # SCRIPT START
  945.  
  946.     # SCRIPT VARIABLES - START
  947.  
  948.     # MYNAME - Assigns the filename used to launch the script to MYNAME to support
  949.     # multiple instances, as this gives each uniquely named copy of the script its
  950.     # own unique log file and PID tracking. This is an attempt at allowing multiple
  951.     # instances of the script to watch multiple different root paths with different
  952.     # settings.
  953.     MYNAME=${0##*/}
  954.  
  955.     # SYS_TMP_PATH - Verify it is not empty
  956.     if [ -z $SYS_TMP_PATH ]; then
  957.         # SYS_TMP_PATH value was not found (empty), use default /tmp path
  958.         SYS_TMP_PATH="/tmp"
  959.     fi
  960.  
  961.     # ALLOW_MULTIPLE
  962.     if [ -z $ALLOW_MULTIPLE ]; then
  963.         # No value was defined. Default to 0 (DISABLED)
  964.         ALLOW_MULTIPLE=0
  965.     fi
  966.  
  967.     # LOGFILE - path and name, uncluding timestamp
  968.     if [ $ENABLELOG -eq 1 ]; then
  969.         TMPLOG="${SYS_TMP_PATH}/.tmp_${MYNAME}_`date +\%Y\%m\%d`.log"
  970.     else
  971.         TMPLOG="/dev/null"
  972.     fi
  973.  
  974.     # LOGGED IN USERS DURING DELETE
  975.     if [ -z $SHOW_USERS_ON_DELETE ]; then
  976.         # If a value isn't defined, then default to showing the logged
  977.         # in users at the time of file deletions.
  978.         SHOW_USERS_ON_DELETE=1
  979.     fi
  980.  
  981.     # Send startup notice to the console
  982.     echo -e "\e[96m\e[1m=======================================================================\e[0m" 2>&1 | tee -a $TMPLOG
  983.     echo -e -n "\e[96m\e[1m$SCRIPT_VER is starting.\e[0m " 2>&1 | tee -a $TMPLOG
  984.     TIMESTAMP newline
  985.     echo -e "\e[96m\e[1m=======================================================================\e[0m" 2>&1 | tee -a $TMPLOG
  986.  
  987.     # DEFINE ADDITIONAL VARIABLES
  988.     SETMASK=0
  989.     SETPRESERVE=0
  990.     SETTEST=0
  991.     SETNOKILL=0
  992.     NOMASK=0
  993.     DEBUG=0
  994.     # SCRIPT VARIABLES - END
  995.  
  996. # CHECK FOR ARGUMENTS - START
  997.     while [[ "$1" != "" ]]; do
  998.         case $1 in
  999.             -nomask)
  1000.                 # Note: NOMASK is just used to identify if this was triggered from the command line, ENABLEMASK is the
  1001.                 # actual value used by the script to determine if masking is on or off.
  1002.                 NOMASK=1
  1003.                 ENABLEMASK=0
  1004.                 if [ $DEBUG -eq 1 ]; then echo -e "\e[45m\e[1mDEBUG:\e[0m The -nomask argument was detected"; fi
  1005.                     # Check if SETMASK has been set and trigger error since they can't be used together
  1006.                     if [ $SETMASK -eq 1 ]; then
  1007.                         echo -e "\e[91m\e[1mERROR!\e[0m You can not use \e[42m\e[1m-setmask\e[0m and \e[42m\e[1m-nomask\e[0m together." 2>&1 | tee -a $TMPLOG
  1008.                         echo "$SCRIPT_VER has terminated." 2>&1 | tee -a $TMPLOG
  1009.                         LOG_CLEAN_OUTPUT
  1010.                         exit 1;
  1011.                     fi
  1012.                     # Check if TESTRUN has been set and notify that nomask is not needed. Non-fatal
  1013.                     if [ $TESTRUN -eq 1 ]; then
  1014.                         echo -e "\e[93m\e[1mNOTICE:\e[0m You do not need to specify the \e[42m\e[1m-nomask\e[0m argument when using \e[42m\e[1m-testrun\e[0m." 2>&1 | tee -a $TMPLOG
  1015.                     fi
  1016.  
  1017.             ;;
  1018.  
  1019.             -setmask=*)
  1020.                 # Note: SETMASK is just used to identify if this was triggered from the command line, ENABLEMASK turns masking
  1021.                 # on (1) or off (0), USEMASK is the mask value being used by the script
  1022.                 if [ $DEBUG -eq 1 ]; then echo -e "\e[45m\e[1mDEBUG:\e[0m The -setmask argument was detected."; fi
  1023.                 SETMASK=1
  1024.                 ENABLEMASK=1
  1025.                 USEMASK=${1:9}
  1026.                 if [ $DEBUG -eq 1 ]; then echo -e "\e[45m\e[1mDEBUG:\e[0m The -setmask= argument captured is: ($USEMASK)"; fi
  1027.                 # Check if NOMASK is has been set and trigger error since they can't be used together
  1028.                 if [ $NOMASK -eq 1 ]; then
  1029.                         echo -e "\e[91m\e[1mERROR!\e[0m You can not use -setmask and -nomask together." 2>&1 | tee -a $TMPLOG
  1030.                         echo "$SCRIPT_VER has terminated." 2>&1 | tee -a $TMPLOG
  1031.                         LOG_CLEAN_OUTPUT
  1032.                         exit 1;
  1033.                     fi
  1034.             ;;
  1035.  
  1036.             -preserve)
  1037.                 SETPRESERVE=1
  1038.                 PRESERVE=1
  1039.                 if [ $DEBUG -eq 1 ]; then echo -e "\e[45m\e[1mDEBUG:\e[0m The -preserve argument was detected"; fi
  1040.             ;;
  1041.  
  1042.             -testrun|-test)
  1043.                 SETTEST=1
  1044.                 TESTRUN=1
  1045.                 if [ $DEBUG -eq 1 ]; then echo -e "\e[45m\e[1mDEBUG:\e[0m The -testrun argument was detected"; fi
  1046.                 # Check if NOMASK has been set and notify that nomask is not needed for testrun. Non-fatal
  1047.                     if [ $NOMASK -eq 1 ]; then
  1048.                         echo -e "\e[93m\e[1mNOTICE:\e[0m You do not need to specify the \e[42m\e[1m-nomask\e[0m argument when using \e[42m\e[1m-testrun\e[0m." 2>&1 | tee -a $TMPLOG
  1049.                     fi
  1050.             ;;
  1051.  
  1052.             -nokill)
  1053.                 SETNOKILL=1
  1054.                 NOKILL=1
  1055.                 if [ $DEBUG -eq 1 ]; then echo -e "\e[45m\e[1mDEBUG:\e[0m The -nokill argument was detected"; fi
  1056.             ;;
  1057.  
  1058.             -delay=*)
  1059.                 RESTARTDELAY=${1:7}
  1060.                 if [ $DEBUG -eq 1 ]; then echo -e "\e[45m\e[1mDEBUG:\e[0m The -delay argument was used, captured delay: ($RESTARTDELAY)"; fi
  1061.             ;;
  1062.  
  1063.             -allowmulti)
  1064.                 ALLOW_MULTIPLE=1
  1065.             ;;
  1066.  
  1067.             -viewlog)
  1068.                 echo "Displaying the most recent log file."
  1069.                 echo
  1070.                 cat $LOGFILE
  1071.                 if [ $? -ne 0 ]; then
  1072.                     echo "$LOGFILE was not found."
  1073.                     echo "The script only checks for logs with today's date. If the system has been up"
  1074.                     echo "for a while, the script may not have had to update any permissions or ownership"
  1075.                     echo "today. Use 'pidof inotifywait' to make sure the script is still running."
  1076.                 # else
  1077.                     # Logfile was found and displayed.
  1078.                 fi
  1079.                 echo "Responded to -viewlog request." >> $TMPLOG
  1080.                 LOG_CLEAN_OUTPUT
  1081.                 exit 0;
  1082.             ;;
  1083.  
  1084.             --help)
  1085.                 echo "If you run $SCRIPT_VER without any arguments, it will"
  1086.                 echo "use the values set in the USER-DEFINED VARIABLES section of the script."
  1087.                 echo "These settings can be overridden by using any of these options at the"
  1088.                 echo "command line."
  1089.                 echo
  1090.                 echo -e "Useage: \e[1mfolder-owner-enforcer <options>\e[0m"
  1091.                 echo
  1092.                 echo -e "  \e[4mOption\e[0m                           \e[4mDescription\e[0m"
  1093.                 echo
  1094.                 echo -e "  \e[1m-setmask=NNN\e[0m          Sets the value of NNN as the mask to enforce\e[0m"
  1095.                 echo -e "                        on the user folders. You can define any valid\e[0m"
  1096.                 echo -e "                        chmod mask.\e[0m"
  1097.                 echo
  1098.                 echo -e "  \e[1m-nomask\e[0m               Disables permissions mask enforcement.\e[0m"
  1099.                 echo -e "                        Permissions will not be enforced on ANY\e[0m"
  1100.                 echo -e "                        items.\e[0m"
  1101.                 echo
  1102.                 echo -e "  \e[1m-preserve\e[0m             Preserves ownership and permissions on\e[0m"
  1103.                 echo -e "                        all existing files and folders, and only\e[0m"
  1104.                 echo -e "                        enforces ownership (and permissions if\e[0m"
  1105.                 echo -e "                        masks are enabled) on NEW items.\e[0m"
  1106.                 echo
  1107.                 echo -e "  \e[1m-nokill\e[0m               Prevents the script from issuing kill commands.\e[0m"
  1108.                 echo -e "                        This also prevents the script from restarting\e[0m"
  1109.                 echo -e "                        when new folders are detected that require a\e[0m"
  1110.                 echo -e "                        restart to establish enforcement on the new\e[0m"
  1111.                 echo -e "                        folder. This should ONLY BE USED IF YOU ARE\e[0m"
  1112.                 echo -e "                        USING INOTIFYWAIT FOR MONITORING OTHER FOLDERS.\e[0m"
  1113.                 echo
  1114.                 echo -e "  \e[1m-allowmulti\e[0m           Allows multiple inotifywait instances so the\e[0m"
  1115.                 echo -e "                        script can be launched to enforce different\e[0m"
  1116.                 echo -e "                        settings for different root folders. Note that\e[0m"
  1117.                 echo -e "                        each instance should be a separately named copy\e[0m"
  1118.                 echo -e "                        of the script.\e[0m"
  1119.                 echo
  1120.                 echo -e "  \e[1m-delay=NN\e[0m             Sets the value of NN to use as the delay when\e[0m"
  1121.                 echo -e "                        the script automatically restarts. This setting\e[0m"
  1122.                 echo -e "                        is ignored when using the -nokill option. The\e[0m"
  1123.                 echo -e "                        purpose is to give administrators enough time to\e[0m"
  1124.                 echo -e "                        set ownership and group on new folders created in\e[0m"
  1125.                 echo -e "                        the root enforcement folder.\e[0m"
  1126.                 echo
  1127.                 echo -e "  \e[1m-test\e[0m                 The -test and -testrun options allow you to run the\e[0m"
  1128.                 echo -e "  \e[1m-testrun\e[0m              script without actually applying or enforcing any\e[0m"
  1129.                 echo -e "                        settings. It simply identifies the folders that would\e[0m"
  1130.                 echo -e "                        be monitored and the settings that would be enforced\e[0m"
  1131.                 echo -e "                        if this were not a test run, then prints them to the\e[0m"
  1132.                 echo -e "                        screen before exiting. Useful to view your configuration\e[0m"
  1133.                 echo -e "                        settings before applying enforcement."
  1134.                 echo
  1135.                 echo -e " \e[1m-viewlog\e[0m               This option reads the current day's log to the terminal.\e[0m"
  1136.                 echo
  1137.                 echo -e " \e[1m--help\e[0m                 Displays this help message."
  1138.                 echo
  1139.                 echo "Responded to --help request." >> $TMPLOG
  1140.                 LOG_CLEAN_OUTPUT
  1141.                 exit 0;
  1142.             ;;
  1143.  
  1144.             *)
  1145.                 # Invalid argument
  1146.                 echo -e "\e[91m\e[1mERROR!\e[0m Invalid argument was detected" 2>&1 | tee -a $TMPLOG
  1147.                 echo "$SCRIPT_VER has terminated." 2>&1 | tee -a $TMPLOG
  1148.                 LOG_CLEAN_OUTPUT
  1149.                 exit 1;
  1150.             ;;
  1151.         esac
  1152.         shift
  1153.     done
  1154. # CHECK FOR ARGUMENTS - END
  1155.  
  1156.     # =======================================================
  1157.  
  1158. # Sleep for 5 seconds to let the system finish loading before validating settings
  1159. echo -e "\e[96m\e[1mInitializing. Please wait...\e[0m"
  1160.     sleep 5
  1161.  
  1162.     # =======================================================
  1163.  
  1164. # VALIDATE SETTINGS - START
  1165.     # Identify the settings (and whether they were started by command line or defined in the script)
  1166.     # Then display messages to inform the user of the settings so they can confirm the script is
  1167.     # using the options they wanted
  1168.  
  1169.     echo -e "\e[96m\e[1m$SCRIPT_VER\e[0m" 2>&1 | tee -a $TMPLOG
  1170.     echo -e "\e[1mEnforcement Settings:\e[0m" 2>&1 | tee -a $TMPLOG
  1171.  
  1172.     # USEMASK - START
  1173.     if [[ ! -z $USEMASK ]]; then
  1174.         # Check the first two characters of the USEMASK value as a basic
  1175.         # verification that a correctly formatted mask was specified.
  1176.  
  1177.         if [[ $SETMASK -eq 1 ]]; then
  1178.             # -setmask command line option message
  1179.             echo -e "  The \e[1m-setmask\e[0m option was specified at the command line."
  1180.             echo -e "  This overrides any mask value set in the script."
  1181.             echo -e "  The mask you have specified is: \e[1m$USEMASK\e[0m." 2>&1 | tee -a $TMPLOG
  1182.         fi
  1183.  
  1184.         VALIDATEMASK
  1185.  
  1186.     fi
  1187.     # USEMASK - END
  1188.  
  1189.     # VALIDMASK - START - Value of (1) Means the mask has been validated, otherwise assume invalid mask
  1190.     if [[ $ENABLEMASK -eq 1 && $VALIDMASK -eq 1 ]]; then
  1191.         if [[ $TESTRUN -eq 1 ]]; then
  1192.             echo -e "  \e[1mPermissions to enforce:\e[0m \e[1mTest Run Mode\e[0m" 2>&1 | tee -a $TMPLOG
  1193.             echo "    permissions will not be enforced. If enforcement was" 2>&1 | tee -a $TMPLOG
  1194.             echo -e "    enabled, permissions \e[1m$USEMASK\e[0m would be enforced." 2>&1 | tee -a $TMPLOG
  1195.         else
  1196.             echo -e "  \e[1mPermissions to enforce:\e[0m \e[1m$USEMASK\e[0m" 2>&1 | tee -a $TMPLOG
  1197.         fi
  1198.     fi
  1199.     # VALIDMASK - END
  1200.  
  1201.     # ENABLEMASK - START
  1202.     if [[ $ENABLEMASK -eq 0 ]]; then
  1203.         echo -e "  \e[1mMasks Disabled\e[0m" 2>&1 | tee -a $TMPLOG
  1204.         echo "    Permissions masks are disabled and will not be enforced." 2>&1 | tee -a $TMPLOG
  1205.     fi
  1206.     # NOMASK - END
  1207.  
  1208.     # VALIDATE DELAY - START
  1209.     # NOKILL is OFF
  1210.     if [ $NOKILL -ne 1 ]; then
  1211.         if [ ! -z $RESTARTDELAY ]; then
  1212.             # There is a value in RESTARTDELAY and NOKILL is NOT enabled, make sure it's a number, and it's higher than 0
  1213.             if [ $RESTARTDELAY -gt 0 ]; then
  1214.                 # The specified delay is valid
  1215.                 validDelay=1
  1216.             else
  1217.                 echo -e "\e[91m\e[1mERROR!\e[0m \e[1mRESTARTDELAY\e[0m value is not valid!" 2>&1 | tee -a $TMPLOG
  1218.                 echo "  Must be a number higher than 0." 2>&1 | tee -a $TMPLOG
  1219.                 echo "$SCRIPT_VER has terminated." 2>&1 | tee -a $TMPLOG
  1220.                 LOG_CLEAN_OUTPUT
  1221.                 exit 1;
  1222.             fi
  1223.         # else
  1224.         fi
  1225.  
  1226.         if [ $validDelay -eq 1 ]; then
  1227.             # There's a value assigned to RESTARTDELAY and it has been verified that it is a valid number
  1228.             echo -e "  \e[1mRestart Delay:\e[0m \e[1m$RESTARTDELAY seconds\e[0m" 2>&1 | tee -a $TMPLOG
  1229.         #else
  1230.         fi
  1231.     # NOKILL is ON
  1232.     else
  1233.         echo -e "  \e[1mNOKILL\e[0m is \e[1mENABLED\e[0m - Script will \e[1mNOT\e[0m automatically restart."
  1234.         echo -e "  If new watches need to be established, you will need to restart manually."
  1235.     fi
  1236.     # VALIDATE DELAY - END
  1237.  
  1238.     # TEST RUN - START
  1239.     if [ $TESTRUN -eq 1 ]; then
  1240.         echo -e "  \e[1mTest Run\e[0m is enabled." 2>&1 | tee -a $TMPLOG
  1241.         echo -e "    When running in \e[1mTest Run Mode\e[0m, enforcement of owner, group, and" 2>&1 | tee -a $TMPLOG
  1242.         echo "    permssions is disabled. This is useful for testing what settings" 2>&1 | tee -a $TMPLOG
  1243.         echo "    would be applied without actually enforcing the settings." 2>&1 | tee -a $TMPLOG
  1244.     fi
  1245.     # TEST RUN - END
  1246.  
  1247.     # PRESERVE - START -Preserves existing owner, group and permissions on all existing items
  1248.     if [ $PRESERVE -eq 1 ]; then
  1249.         echo -e "  \e[1mPreserve\e[0m is \e[1mENABLED:\e[0m" 2>&1 | tee -a $TMPLOG
  1250.         echo -e "    \e[1mOwner\e[0m and \e[1mGroup\e[0m will only be enforced on \e[1mNEW\e[0m items." 2>&1 | tee -a $TMPLOG
  1251.         echo "    Properties of \e[1mexisting\e[0m items will \e[1mnot\e[0m be changed." 2>&1 | tee -a $TMPLOG
  1252.     else
  1253.         # Preserve is off so enforcing owner, group and permissions on all existing and new items
  1254.         echo -e "  \e[1mPreserve\e[0m is \e[1mDISABLED:\e[0m" 2>&1 | tee -a $TMPLOG
  1255.         echo -e "    \e[1mOwner\e[0m and \e[1mGroup\e[0m will be enforced on \e[1mALL\e[0m new and existing items." 2>&1 | tee -a $TMPLOG
  1256.     fi
  1257.     # PRESERVE - END
  1258.  
  1259.     # NOKILL - START
  1260.     if [ $NOKILL -eq 1 ]; then
  1261.         echo -e "  \e[1mNo Kill\e[0m is enabled." 2>&1 | tee -a $TMPLOG
  1262.         echo "    Running instances of inotifywait will NOT be killed." 2>&1 | tee -a $TMPLOG
  1263.     fi
  1264.     # NOKILL - END
  1265.  
  1266.     # ALLOW_MULTIPLE -allowmulti
  1267.     if [ $ALLOW_MULTIPLE -eq 1 ]; then
  1268.         echo -e "  \e[1mAllow Multiple\e[0m is enabled." 2>&1 | tee -a $TMPLOG
  1269.         echo "    Unknown running instances of inotifywait will NOT be killed." 2>&1 | tee -a $TMPLOG
  1270.     fi
  1271.  
  1272.     # LOGGING - START
  1273.     if [ $ENABLELOG -eq 1 ]; then
  1274.         echo -e "  \e[1mLogging\e[0m is enabled." 2>&1 | tee -a $TMPLOG
  1275.     else
  1276.         echo -e "  \e[1mLogging\e[0m is disabled." 2>&1 | tee -a $TMPLOG
  1277.     fi
  1278.     # LOGGING - END
  1279.  
  1280.     # ROOTPATH CHECK VALUE - START - Checks the ROOTPATH variable for trailing slash, add it if it is missing
  1281.     #                   along with an asterisk (wildcard). Also stores the defined ROOTPATH to the BASEPATH
  1282.     #                   variable (without a trailing slash) for comparative operations later.
  1283.  
  1284.     # There is a trailing slash. Remove for storing in BASEPATH, add an asterisk to ROOTPATH
  1285.     if [[ ${ROOTPATH} == */ ]]; then
  1286.         BASEPATH="${ROOTPATH%/*}"
  1287.         ROOTPATH="${ROOTPATH}*"
  1288.  
  1289.     else
  1290.     # There is no trailing slash. Store ROOTPATH in BASEPATH, then add a trailing slash and asterisk to ROOTPATH
  1291.         BASEPATH="${ROOTPATH}"
  1292.         ROOTPATH="${ROOTPATH}/*"
  1293.     fi
  1294.  
  1295.     # CHECK PATH IS VALID
  1296.     if ! [ -d "${BASEPATH}/" ]; then
  1297.         # ROOTPATH is NOT a directory
  1298.         echo -e "\e[91m\e[1mERROR!\e[0m Invalid Path!" 2>&1 | tee -a $TMPLOG
  1299.         echo "The path defined as the ROOTPATH variable is not a valid folder. Please check the" 2>&1 | tee -a $TMPLOG
  1300.         echo "path assigned to ROOTPATH in the folder-owner-enforcer script." 2>&1 | tee -a $TMPLOG
  1301.         echo "$SCRIPT_VER has terminated." 2>&1 | tee -a $TMPLOG
  1302.         LOG_CLEAN_OUTPUT
  1303.         exit 1;
  1304.     fi
  1305.  
  1306.     # ROOTPATH CHECK VALUE - END
  1307. # VALIDATE SETTINGS - END
  1308.  
  1309.     # ==========================================================================================================
  1310.  
  1311. # RUN SCRIPT FUNCTIONS - START
  1312.  
  1313.     # Update the formatting on the current log file
  1314.     LOG_CLEAN_OUTPUT
  1315.  
  1316.     # Run the KILL_INOTIFY function to terminate any existing running instances of inotifywait
  1317.     KILL_INOTIFY
  1318.  
  1319.     # Check if this is a test run or not to determine if enforcement should be enabled.
  1320.     if [ $TESTRUN -eq 1 ]; then
  1321.         # This is a test run, just run the SCANFOLDERS function
  1322.         SCANFOLDERS
  1323.  
  1324.     else
  1325.         # This is not a test run, so scan for folders and enable enforcement.
  1326.         SCANFOLDERS
  1327.         ENFORCEMENT
  1328.     fi
  1329.  
  1330. # RUN SCRIPT FUNCTIONS - END
  1331.  
  1332. # SCRIPT END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement