script superuser permission problem

I’m updating an opensuse script to simplify working with clamav command line application. To get access to mswin partitions, I need to click that partition to unlock all of them for that session to run scanvirus. However, in doing this, I unlock those partitions without the ability to re-lock them until after the session(reboot).

Click mswin partition-> enter admin password.
Run scanvirus

Those partitions are still unlocked for this session.

I’v tried superuser alone, but those register as not mounted until do a manual click and admin password. On the linux scan, it scans all files under superuser/admin mode, but only on that command. I need to be access win partitions under superuser only. Then after the command is finished they are relocked and maybe unmounted.

Hopefully, i’v made this clear enough. I need help to fix this security flaw. The problem isn’t specific to the code. So, i’m not posted. It’s general problem.

Hi,

So you need to mount those partitions using the mount command, as root then run your clamav script against those partitions.

The flow of the script should be something like this.

  1. Check if the partitions are connected/detected by using some tools to parse disk ,or print an error or exit the script if they are not detected.
  2. Mount them using the mount command or print an error and exit the script if mounting failed.
  3. Run your script against those disk/partitions.
  4. Unmount them after a successful scan or whatever your script does with those partitions.

Some useful tools/commands that you might need.

For disk/partitions info

  1. fdisk
  2. blkid

Mounting and unmounting the disk/partition

  1. mount
  2. umount

A simple loop to check if the disk are mounted and execute your script if they are mounted.

until mount **/dev/blah_blah**; do **myscript_that_does_something_with_my_windose_disk_partitions**; done

Just my two cents…

OK, I’ll do some research on the subject.

The instructions have me click and get permissions to those drives then copy and paste the drive location into mswin paths. Problem, how do I get the user to modify “mswin_paths” file without asking them to unlock them is the first place.

click on mswin dir (admin password)
copy paths into “mswin_paths”
[ready to run scanner]

In file manager, right click on mswin partition to get the mswin path without using the superuser password. Get the pathname without unlocking it. However directories aren’t in the media folder until I unlock it. The user can’t get those mswin_paths until they unlock the folder. Once they have them, the script can mount and unmount them from the mswin_paths file.

/media/mswin764bit/ media is empty until I unlock it.

Does that make sense?

Hi,

You seem to be relying on the file manager mounting your win partition. That is fine if you want it to work that way but what i have suggested is mounting the partition using the mount command and not using the file manager. Parsing the output of

blkid -o list

as root is a good start, you should have all the info you need in the disk partition, label and if it is mounted or not. Using the mount command to mount the partition instead of relying on the file manager to mount it for you. Good luck.

I see now the general formula to do that. Now, i’v done parsing many times in programing. I need the specific bash commands to do that.

strlen, string(index), copycharacter, for, while: building the line for the mount command. I good example web pages to learn from. The while and for aren’t that different from [c] programing.

I need to understand blkid better. I have a good one for that now.

Thanks.

Hi,

A while read loop would be a start.

while read -r line; do 
   echo "$line"
done < <(blkid -o list)

Now to test if you have

mswin764bit

Add a test pattern matching to see if mswin764bit is in the output of blkid -o list

while read -r line; do 
    $line = *mswin764bit* ]] && echo "$line"
done < <(blkid -o list)

If you want to just test if a pattern is in the output of blkid then you can just use grep or exit with an error message if there is no match.


Label=mswin764bit
grep -q "$Label" < <(ListDisk) || die "Sorry can't find disk/partition with the label: $Label"

where die is a function that needs a warn function, of course this warn and die function should be define first before you can use it. Meaning this code below should go first before the grep or any other line of code that you want to use the warn and die function.

warn() {
  printf '%s
' "${BASH_SOURCE##*/}: $*" >&2
}

die() {
  local st=0
  case $2 in
    *^0-9]*|'') :;;
    *) st=$2;;
  esac
  warn "$1"
  exit "$st"
}

Here is how i would do it.

First define the variables so it is easy to just change the values in the future.

Label=mswin764
CheckMount='(not mounted)'
MountPoint='/mnt'
regex1=$Label.+$CheckMount
regex2=$Label.+\/.+

Define a function for blkid including it’s options.

ListDisk() {
  blkid -o list
}

First check if there is indeed a disk with the Label you have defined

grep -q "$Label" < <(ListDisk) || die "Sorry can't find disk/partition with the label: $Label"

Now parse ListDisk which is function that calls blkid and it’s options, with a while read loop and some test for regex that you have defined.

while read -r line; do
  if  $line =~ $regex1 ]]; then
    Disk=${line%% *}
    mount "$Disk" "$MountPoint" || die "$Disk cannot be mounted on $MountPoint!"
    printf '%s
' "${Disk} has been mounted on $MountPoint"
  elif  $line =~ $regex2 ]]; then
    Disk=${line%% *}
    line="${line#*$Label}"
    line="${line% *}"
    printf '%s
' "$Disk is already mounted on ${line// }"
  fi
done < <(ListDisk)

The code above has some PARAMETER EXPANSION to extract the disk and it’s label plus some regex (which I’m not good at ) to test for a match.
It should mount your partition in /mnt if it is not mounted and print a message if it is already mounted.

Now the last thing is to add your actual clamav script/code and point it to /mnt or anywhere/place/directory that you have defined as the mount point.

clamav blah..blah.. /mnt

Of course if you need to unmount that partition then you need to add the umount command.
You can take that code piece by piece and see how it works. Again that code is just an example of how I would do it and I’m not saying that is correct nor best approach but at least it is a working bash solution. :wink:

Can I setup blkid to mask out all but ntfs and vfat file systems?

http://manpages.courier-mta.org/htmlman8/blkid.8.html

Another command that list devices.

http://manpages.courier-mta.org/htmlman8/lsblk.8.html

Thanks.

Hi,

I’m not sure if blkid has that option and I’m sorry since I am not a native English speaker I cannot decipher the man pages for you :wink:
lsblk does not support gpt partitions and the file system is not shown if you don’t run it as root AFAIK.

If you just want to print the print/extract vfat and ntfs, you can just parse it (which I have suggested before)

while read -r line; do 
    $line != *@(vfat|ntfs)* ]] && continue
   echo "$line"
 done < <(blkid -o list)

or using the -a option to read


while read -ra line; do 
    ${line[1]} != *@(vfat|ntfs)* ]] && continue
   echo "${line@]}"
 done < <(blkid -o list)

Those two examples needs an

shopt -s extglob

enabled on the script the caveats on the first example is one needs to make sure that the only vfat and ntfs string is in the second column/field while the second example using the --a option to read will make sure that it only matches the line with strings vfat and ntfs which is found ONLY on the second field/column. Now time to write your script. :slight_smile:

Hi,

Here is a quick draft that comes into mind.

#!/usr/bin/env bash


shopt -s extglob


while IFS=' ' read -ra line; do
   ${line[1]} = @(vfat|ntfs) && ${line[3]} = '(not' ]] || continue
  
  if  ! -d /mnt/"${line[2]}" ]]; then
    mkdir /mnt/"${line[2]}" && mount "${line[0]}" /mnt/"${line[2]}"
  else 
    mount "${line[0]}" /mnt/"${line[2]}"
  fi
done < <(blkid -o list)

Now let us take that code piece by piece.

while IFS=' ' read -ra line

This code is using IFS and the value of spaces as the separator
The -r option is needed because you are working with your favorite windows disk/partition/file_system
The -a option to read is to create an array in a single line ( create fields/columns which count starting from zero 0 )
The line is a varialbe.

 ${line[1]} = @(vfat|ntfs) && ${line[3]} = '(not' ]] || continue

The is a form of test and it should end with a closing ]]
The ${line[1]} is the second field/column, mind you zero is the first field which is “${line[0]}”
The @(pattern1|pattern2|pattern3|…) is an extglob feature (IIRC) which means if field/column 2 matches vfat or ntfs.
The && ${line[3]} = ‘(not’ means if the field/column 4 match the pattern ‘(not’
The || continue means if lines that do not match both the test skip or ignore those lines.
So in the end you will have only lines that has vfat or ntfs in the second field/column and ‘(not’ in the fourth field/column.

if  ! -d /mnt/"${line[2]}" ]]; then

Test /mnt/"${line[2]}" is not an existing directory, the ! negates. Mind you that “${line[2]}” is the third field/column which is the disk label.

mkdir /mnt/"${line[2]}" && mount "${line[0]}" /mnt/"${line[2]}"

Create directories inside /mnt with the name being the value of “${line[2]}” (disk label)
Then mount the corresponding disk “${line[0]}” in “${line[2}” which is the disk label.

else 
    mount "${line[0]}" /mnt/"${line[2]}"

If the /mnt/"${line[2]}" is an existing directory then just mount the disk “${line[0]}” inside it.

Now

clamav blah..blah. /mnt/*/

assuming clamav can do multiple directories at once since the */ globe will expand to the directories under /mnt.

One more thing, I DO NOT advise scripting when it comes to removing/deleting directories (at least not yet). It has a lot of common pitfalls that you should know about. Since you might want to remove/delete those created directories under /mnt or whatever directory you have chosen to use as the parent directory for the mount point. One needs to check if the directory is empty before deleting it but if one does not have proper permission on the directory in question then that directory is always empty so it is a nightmare waiting to happen if you’re not careful. A good classic example of that pitfall is the infamous steam bash code that manage to delete the entire / directory due to the lack of testing and the author neglected to exit the script when the test failed.

Now I think I’m done here…

I’m stuck. This loop is a common used structure for doing something only once. I’m trying to read the first two lines of the output. Then read it word by word. I’ve tried using numbers instead, that didn’t work either. I want to leave out arrays for now. Can you fix this code? I need to understand what i’m doing wrong. Thanks

         while read -r line; do 
           scanvirus_flag="false"           scanvirus_flag=0
           if   "$scanvirus_flag" = "false" ]; then         #if  scanvirus_flag=0]; then
             scanvirus_flag="true"        #scanvirus_flag=1
             printf "%s
" $line
             read -r line
             printf "%s
" $line
             read -r line
             break
           fi

#           if  "$parm_device" = "*--------------------*" ]; then
#               read -r parm_device
#           fi
#          printf "%s " $parm_device
           
#           read -r parm_file_system_type
#           printf "%s " $parm_file_system_type
           
#           read -r parm_label
#           printf "%s " $parm_label

#          read -r parm_mount_point
#           if  "$parm_mount_point" = "(not" ] ||  "$parm_mount_point" = "(in" ]; then
#             printf "%s " $parm_mount_point
#             read -r parm_mount_point
#             printf "%s " $parm_mount_point
#           else
#             printf "%s " $parm_mount_point
#           fi
    
#           read -r parm_uuid
#           printf "%s
" $parm_uuid
   
         done < <(blkid -o list)

Hi,

It seems every time you’re question is changing whenever i have an answer rotfl!

Now instead of code that even you cannot understand what is happening (which is your own code)
Why not just ask and explain what are you really trying to do. :wink:

It seems every time you’re question is changing whenever i have an answer rotfl!

Now instead of code that even you cannot understand what is happening (which is your own code)
Why not just ask and explain what are you really trying to do. :wink:

I’ve been programing a very long time. For general programing experience and training, I know nearly every skill and technical debugging. Bash scripting is totally new to me. How is not a problem. The specific commands to get the job done on sections of code are the problem. Your snips of very useful, but sometimes i’m confused what your doing. I can’t use snips, if I don’t understand how they work or what they do. I’m learning it as go. My mind is always three steps ahead for the formula as whole.

Thanks to you for all those snips. Also, the bug in that code was a novice error. One of those DUH! moments… rotfl! I will not speak of it…

I’v fixed that bug. I’m going to use word array code snip to parse the output. Then use that to mount, scan, and unmount. I’ll post on here if I need help again. I just need the time to write out the new code.

Hi,

I don’t doubt your experience in programming also I’m willing to give some handholding along the way if need be :wink:
but for us to make progress we should be on the same page otherwise we will be going on like an infinite loop.

I saved the whole page as reference, adding to very crowded “opensuse tech folder”. Every bit of hand holding is helpful.
Linux bash is all new to me. Each programing language is has slightly different structure, but general programing use the same basic structure and debugging code. This is how many I know. For reference, but not bragging. :wink:

Basic (interpreter ATARI 8-BIT), ASM MAC/65 and ACTION! (ATARI 8-BIT), ADA, Pascal, and C. Each one has it’s quirks, including Linux bash. Like the syntax errors aren’t always on the line shown. Missing or 3 quotes in one line are a joy to find and fix… (sarcasm)

Good news: The whole script works now. It finds and scans all vfat and ntfs file systems, no need for user files. It found a possible virus in my MSWIN764 system. Which I waited to reboot and scan using my win scanners. OPPS, didn’t delete right away. see next line. Need to write control-c trap I found, refine instructions, fix superuser and script access issues. “.snapshots”? (excluded)

Bad news: my win system boots (on grub2 - click win) to “boot loader not found”. My linux system works as normal, no click boot to windoze (again - rolling eyes). So, I need to figure out what went haywire, attempt system recovery: how much damage is there and how to fix it. Maybe just quick linux boot loader fix or complete win install or total recovery after retrieving data files. Keep my win7 installer from destroying my Linux partions again.

This current problem is fixed. I’ll post again, once I decode what’s wrong with windoze. Thank you once again for your hand holding posts. I do it in a different format for coding than you, but it’s all the same in results. lol!

To all: It’s neat, clean, and easy to read, one self-contained script for all functions needed. It will setup icons on your desktop. I’ll put a creative common license on release version.