We can test if a directory is writable by the uid of the current process:
if [ -w $directory ] ; then echo \'Eureka!\' ; fi
But can anyone
One funny possibility (but it's not bash anymore) is to make a C program with the suid flag, owned by mysql.
Create this wonderful C source file, and call it caniwrite.c
(sorry, I've always sucked at choosing names):
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char* argv[]) {
int i;
for(i=1;i<argc;++i) {
if(eaccess(argv[i],W_OK)) {
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
Compile:
gcc -Wall -ocaniwrite caniwrite.c
Move it in whatever folder you like, /usr/local/bin/
being a good choice, change it's ownership and set the suid flag: (do this as root)
# mv -nv caniwrite /usr/local/bin
# chown mysql:mysql /usr/local/bin/caniwrite
# chmod +s /usr/local/bin/caniwrite
Done!
Just call it as:
if caniwrite folder1; then
echo "folder1 is writable"
else
echo "folder1 is not writable"
fi
In fact, you can call caniwrite
with as many arguments as you wish. If all the directories (or files) are writable, then the return code is true, otherwise the return code is false.
Here's a long, roundabout way of checking.
USER=johndoe
DIR=/path/to/somewhere
# Use -L to get information about the target of a symlink,
# not the link itself, as pointed out in the comments
INFO=( $(stat -L -c "%a %G %U" "$DIR") )
PERM=${INFO[0]}
GROUP=${INFO[1]}
OWNER=${INFO[2]}
ACCESS=no
if (( ($PERM & 0002) != 0 )); then
# Everyone has write access
ACCESS=yes
elif (( ($PERM & 0020) != 0 )); then
# Some group has write access.
# Is user in that group?
gs=( $(groups $USER) )
for g in "${gs[@]}"; do
if [[ $GROUP == $g ]]; then
ACCESS=yes
break
fi
done
elif (( ($PERM & 0200) != 0 )); then
# The owner has write access.
# Does the user own the file?
[[ $USER == $OWNER ]] && ACCESS=yes
fi