Solaris bash bug in testing extended ACLs; works OK in ksh

I've got a shell script that uses file tests extensively (-x, -r, -f, etc.).  It works well in all environments -- till now.  For some reason, the tests work on Solaris 10 under ksh, but not under bash.  I'm stumped.

$ uname -a
SunOS xxx.example.com 5.10 Generic_147440-27 sun4v sparc SUNW,Sun-Blade-T6300

# Permissions test succeeds in ksh
-bash-3.00$ ksh
$ [ -r "/test/scripts/myfile" ] && echo yes || echo no
yes

Open in new window

# Permissions test fails for bash
$ bash
-bash-3.00$ [ -r "/test/scripts/myfile" ] && echo yes || echo no
no

Open in new window

The same results occur with "-x" instead of "-r".  

The script is being run by user "dbadmin" in group "dbadmin".  The standard file permissions would not allow this particular user to access to the file, but the extended permissions do.  The permissions have been set by a script, so I know that they are the same as they are on a number of other systems.  The full set of permissions is included below, but the relevant lines are

-rwxrwx---+  1 abc      abc        18899 Sep 21 14:15 /test/scripts/myfile
     group:dbadmin:-------A---C--:------:deny
     group:dbadmin:r-x---a---c--s:------:allow

Open in new window

$ ls -V /test/scripts/myfile
-rwxrwx---+  1 abc      abc        18899 Sep 21 14:15 /test/scripts/myfile
            owner@:rwxp--aA--cC-s:------:allow
            owner@:--------------:------:deny
            group@:-------A---C--:------:deny
            group@:rwxp--a---c--s:------:allow
        group:root:-------A---C--:------:deny
        group:root:r-x---a---c--s:------:allow
         group:abc:-------A---C--:------:deny
         group:abc:rwxp--a---c--s:------:allow
     group:pkguser:-------A---C--:------:deny
     group:pkguser:r-x---a---c--s:------:allow
    group:pkgadmin:-------A---C--:------:deny
    group:pkgadmin:rwxp--a---c--s:------:allow
     group:dbadmin:-------A---C--:------:deny
     group:dbadmin:r-x---a---c--s:------:allow
            group@:-------A---C--:------:deny
        group:root:-w-p---A---C--:------:deny
         group:abc:-------A---C--:------:deny
     group:pkguser:-w-p---A---C--:------:deny
    group:pkgadmin:-------A---C--:------:deny
     group:dbadmin:-w-p---A---C--:------:deny
         everyone@:------a---c--s:------:allow
         everyone@:rwxp---A---C--:------:deny

Open in new window

Any ideas?
APlusDadAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

APlusDadAuthor Commented:
Two supplementary notes:
1)  The enclosing directories have similar permissions.  In particular, the group dbadmin has "r-x" access to all of them.

2)  Out of whimsy and desperation, I tried "bash --posix", but it didn't help.
0
arnoldCommented:
If you take out the or?

If [ -r "/test/scripts/myfile" ] ; then
          echo "yes"
else
       echo no
fi
0
APlusDadAuthor Commented:
No difference, I'm afraid.  The original code is actually in the form you suggest; I shortened it for the example.

I also tried explicitly using the keyword "test", and I tried double brackets:
  [[ -r /test/scripts/myfile ]] && echo yes
with the same results.
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

skullnobrainsCommented:
i could not reproduce the same problem with acls on a linux box using bash 4.2.45

did you try using "/usr/bin/test" instead of the [ -r .... ] construction ? (the whole path is needed on order to use the command instead of bash's builtin)

either bash ignores acls altogether or caches them improperly and ignores the changes you made in your script. the latter would be very bash-like because bash has a history of trying to go fast and messing up various stuff that work in any other shell in the process
0
APlusDadAuthor Commented:
Thanks very much for the response.

1) I cannot reproduce this problem on any version of Linux, either.  It is only on this one Solaris server.

2) You raise a good point; I neglected to include the version of bash on this system:
    GNU bash, version 3.00.16(1)-release (sparc-sun-solaris2.10)
Perhaps I can get the site to install bash 4.1 from sunfreeware.com

3)  It's not a caching issue; the permissions are not changed in the current session.

4)   I had somehow forgotten to try the executable version of test -- it does work properly.  At least this gives me an option to pursue, though I am loathe to implement it for two reasons:

 -  I'll have to go through a suite of scripts line by line and find each of these tests, change them, and test the results.
 -  These scripts run on a number of systems; either I have to change the "standard" to incur the overhead of spawning a program for each test (bleah!), or I have to have a custom version of the scripts for this system (double bleah!).

I suppose I might take an in-between course, and replace each test with a function call.  I am guessing that these will be cheaper to run on systems that don't require a spawn.
0
skullnobrainsCommented:
i guess bash has no proper integrations with acls. this may be solaris-secific, filesystem-specific ... i'd be happy to see a truss or equivalent trace of what bash does when the builtin test is called if you can provide it together with the output of "uname -a" and the filesystem (ufs ? zfs ?)

there are other options to consider

- don't use bash... why would you on solaris anyway ?

- use alias : "alias test=/usr/bin/test" which takes precedence over builtins. you can stick this on top of each script or possibly in .bashrc for example
0
APlusDadAuthor Commented:
Thanks again.  I've attached three files of truss output:  
- one successful test with ksh
- the same test which fails under bash
- a test under bash which succeeds because it does not require extended ACLs

Details of each are in the respective files.

As to why I'm using bash on this system -- these are not intended to be Solaris scripts; they are supposed to be fairly generic.  They all ran under ksh until about a year ago; I finally made the switch when I installed on a system without ksh.  (I wait a long time to make these kind of changes, since the scripts need to run on some fairly old systems.)  Plus, I was glad to take advantage of the additional built-ins.  But I neglected to test on this particular system, and now I have scripts that don't port.

I love the alias idea; much better than using a function.
truss.zip
0
skullnobrainsCommented:
the ksh truss shows ksh is making use of the access system call (ie asking the kernel about access rights instead of working them out internally)

unfortunately, the bash trusses don't actually show the command being performed but rather being read character by character and printed on stderr likewise

if you have the complete truss, i'm sure we can determine why it does not work in bash. unfortunately, it probably won't help working it out. anyway, using the system's test is a reasonable workaround. i'd go the alias way in your case.

----

creating portable shell scripts is quite a pita, mainly because of bash and dash and a few differences in systems (mainly non posix-compliant linux behaviour). in bash, you'd definitely need to :
- don't use builtin test
- don't use builtin expr
- don't use signals (you can send and capture sigterms usually, though)
- don't rely on the fact that a pipe's output is supposed to be the output from the last command in the pipe. don't try to cheat using curly or regular brackets : it won't work all the time
- don't ever use stat either builtin or non-builtin except for mapping names to inodes or retrieving file sizes

... unfortunately, test and expr are not very consistent across systems but if you refrain from using any flag with expr and using basic test syntaxes, it usually works out properly using the system's.

then if you want to work on portability, scripting in basic sh will be usually ok on most systems.

dash additionally does not execute while loops in a subshell and does not handle variable scopes properly in this respect

... and if you expect portability to linux systems, you'll also have to handle changing switches in many commands, the bunch of bugs in gnu's sed, the lack of ctime on files... and quite a lot of other expectable problems

---

bottom line is you'll need quite some experience to build portable shell scripts and you'll probably had better use to perl or php scripts or a single shell such as zsh in quite a few cases (triple beah in such cases, i guess...)
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
APlusDadAuthor Commented:
Although the answer was not what I'd hoped, there were some helpful suggests -- and the supplementary info was above and beyond the call.  Thanks!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Shell Scripting

From novice to tech pro — start learning today.