javac called from perl script

Hi all,

I’m trying to write a packaging script in perl on a Suse 11.0 system – basically, it checks out java files from our cvs system, compiles them with javac and creates a bundle. Since the files must be assigned to a special user, I sudo the script and switch the user/group by changing $> and $).
The whole script works basically, however I’ve noticed a very weird problem: although all folders created and files checked out from the cvs do have the right owner/group, the folder/files generated by javac still belong to root:root!

I’ve been able to reproduce the problem in a very short script:


#!/usr/bin/perl
use strict;
$) = 8; # group 'www'
$> = 1357; # user 'docu-user'
mkdir "test";
my $command = "/usr/bin/javac -cp \"\" -d test test.java";
system $command;

Note 1: you’ll notice the empty classpath in the javac call. If I don’t add that, then I get an error message:

/usr/bin/javac: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory

I have absolutely no idea why not setting the classpath (especially to empty) prevents javac from finding its library, but well.

Note 2: test.java contains a very basic HelloWorld program declared in package pack.test.

Now if I run this script with sudo, everything works fine, however directory test contains the following:


> sudo perl test2.pl
> ls -alR test
test:
total 3
drwxr-xr-x 3 docu-user www   512 2009-11-24 15:54 .
drwxrwxrwx 4 pagod     users 512 2009-11-24 15:54 ..
drwxr-xr-x 3 root      root  512 2009-11-24 15:54 pack

test/pack:
total 3
drwxr-xr-x 3 root      root 512 2009-11-24 15:54 .
drwxr-xr-x 3 docu-user www  512 2009-11-24 15:54 ..
drwxr-xr-x 2 root      root 512 2009-11-24 15:54 test

test/pack/test:
total 3
drwxr-xr-x 2 root root 512 2009-11-24 15:54 .
drwxr-xr-x 3 root root 512 2009-11-24 15:54 ..
-rw-r--r-- 1 root root 424 2009-11-24 15:54 Test.class

Does anyone have any idea why this happens? As I said before, this doesn’t happen when I’m calling cvs or creating other files/folders. How can javac create files as root although it’s supposedly not the active user?? I’ve tried in several different shells, with different users, the result is always the same :expressionless:

Thx a lot for any help anyone can provide! :slight_smile:

Pagod

You might want to read up on the distinction between real and effective uids and use POSIX::setuid instead of assigning to $>.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

How do you figure it is not the active user? You are running ‘sudo perl
test2.pl’ which means that ‘root’ is being used. When you make the
‘system’ call in Perl it makes that as root as well. If you want javac to
run as a lesser user then add the ‘sudo’ before it in the $command
variable and specify an alternate user (the one with ID 1357 for example).

Good luck.

pagod wrote:
> Hi all,
>
> I’m trying to write a packaging script in perl on a Suse 11.0 system –
> basically, it checks out java files from our cvs system, compiles them
> with javac and creates a bundle. Since the files must be assigned to a
> special user, I sudo the script and switch the user/group by changing $>
> and $).
> The whole script works basically, however I’ve noticed a very weird
> problem: although all folders created and files checked out from the cvs
> do have the right owner/group, the folder/files generated by javac still
> belong to root:root!
>
> I’ve been able to reproduce the problem in a very short script:
>
>
> Code:
> --------------------
>
> #!/usr/bin/perl
> use strict;
> $) = 8; # group ‘www’
> $> = 1357; # user ‘docu-user’
> mkdir “test”;
> my $command = “/usr/bin/javac -cp “” -d test test.java”;
> system $command;
>
> --------------------
>
>
> Note 1: you’ll notice the empty classpath in the javac call. If I don’t
> add that, then I get an error message:
>
> Code:
> --------------------
> /usr/bin/javac: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory
> --------------------
>
> I have absolutely no idea why not setting the classpath (especially to
> empty) prevents javac from finding its library, but well.
>
> Note 2: test.java contains a very basic HelloWorld program declared in
> package pack.test.
>
> Now if I run this script with sudo, everything works fine, however
> directory test contains the following:
>
> Code:
> --------------------
>
> > sudo perl test2.pl
> > ls -alR test
> test:
> total 3
> drwxr-xr-x 3 docu-user www 512 2009-11-24 15:54 .
> drwxrwxrwx 4 pagod users 512 2009-11-24 15:54 …
> drwxr-xr-x 3 root root 512 2009-11-24 15:54 pack
>
> test/pack:
> total 3
> drwxr-xr-x 3 root root 512 2009-11-24 15:54 .
> drwxr-xr-x 3 docu-user www 512 2009-11-24 15:54 …
> drwxr-xr-x 2 root root 512 2009-11-24 15:54 test
>
> test/pack/test:
> total 3
> drwxr-xr-x 2 root root 512 2009-11-24 15:54 .
> drwxr-xr-x 3 root root 512 2009-11-24 15:54 …
> -rw-r–r-- 1 root root 424 2009-11-24 15:54 Test.class
>
> --------------------
>
>
> Does anyone have any idea why this happens? As I said before, this
> doesn’t happen when I’m calling cvs or creating other files/folders. How
> can javac create files as root although it’s supposedly not the active
> user?? I’ve tried in several different shells, with different users, the
> result is always the same :expressionless:
>
> Thx a lot for any help anyone can provide! :slight_smile:
>
> Pagod
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJLC/jiAAoJEF+XTK08PnB5/QUQAKbeFbAnKqd02q4XeXYz4hHW
LFfVz68zvECt7AOjOgzW3VTS/yNqrbBytopMmTMRJGUXjtBCj/TG4NLvtT4DMPWU
ImuAXSZqQkQlPU+hCbRZ9DDoi+Va8r50aYCfPlJZyzYZPUXNdc7NgLwuO1rJmdWx
Vrz2HECUmPWRBtd32adFcyJaCvaJa5VcRbLXGreIrO7DHREdkluuwWKaKnyGq1PI
gOfSx1hAkiQH55LllFVwSIsuINTgSVurznIPYSbkCSyZcxTAgzPbleMyESAaGc4Z
xWTCM/bO1eusFqLfxEnma5otAielWAVvc/qcUrWMh60a/tQpAlvRVCm7142DfS1c
sDFV4EyBKxJNPc7vkRc/zwIFaLTs77rVFYf1iFBfKQAmNGYZjyONiSVAF5zz+B0x
x5zRZZZMAeL2sm4kk38eArzl/5Tzlis8WOgPzYCGNjYjZExqjj87xTQ4mtPHfrCp
OVV5MjjXqx1hDiofOCEEg/XTlGm9NfomMN1wEnhT/thZF4f7SpRq4+c10bM/2Au6
3f2jpw1w/FW88YAFqNpDcz3uPvCK/nANEGVGu3+uH6XCgnYUpwL/drFMCvP/rD/T
o4mJ6efORgcD2CYaAeQ66HmyGxofg1Yz+TCZ+miXFkWLX/g3IxQP7SzIWXMVPm0G
Jitb8gpb5FfObj6/CofX
=c9Hv
-----END PGP SIGNATURE-----

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Perhaps get the output of the env command via the Perl system call to
see what that shows.

Good luck.

ken yap wrote:
> You might want to read up on the distinction between real and effective
> uids and use POSIX::setuid instead of assigning to $>.
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJLC/1pAAoJEF+XTK08PnB5dbcP/0JqwdN1QRZjCWDYAMleG1b8
ItPLNVJeo84Qjnco4KnsJHXTUIqgR+M/YkBPqhomhuTdh/cjsGR9BWDzVNRzQXCw
Spg3pn1IRMgsAmSEgwEriHy/NsU1sByvoNd0fdjy9VhVCCmaoImlN7XUwSbmnreO
JZp45cy+9+/XTU0Ey2SdrD394R3Y0GOP/q/vVR3wEPwcREGmvfNwEQp7Ow8midtZ
Y3JYSl0ob7SM8vJBqT+SlEMf0KC727F36kgVvl/w3lWWOHP7usNWbB7LC46y8wCZ
OkV/d7YZwQ5pFx3N4uzyWyp8aou5PCujMkJiZtiSJDLZDYrHCRlmuUSofRaQGBPH
J3KZ/T2v31LLzC4gp1ooQ6i09Oy8oAYpmYgHZh3vgVsyZfBjgVgPlhKiarS9DpIp
Z9HfmdHB2UGbs432v48JPuvq/VcXXsGKhpmAatud1l6FmmwYfQbk/yplhh98Bylg
5mf9x4217AEAY6nf57wgwVS5IW3zSz3Le7kRfQKxMGHWSqLIgjaPR/r0RdC/i7f2
Y5F256zXItHwiOogHkoH/Eklz+VcFKtF7akqPwsyXthoFbkbrO/rbA+q2IxqhrjE
A+RiBEH3Wd1l+yQaxVakwOxQcdGG9d26omJQHT7KU3v5fEckoJPO86qx9m2rIw4T
QJQBUUQe7ysPp4YhBoSs
=gjw6
-----END PGP SIGNATURE-----

Thx a lot for the answers!

Well, I’m changing the effective user ID by reassigning $>. If you look at the output, you’ll notice that the ‘test’ directory has been created with the right owner/group. Creating a directory using “system ‘mkdir test’” or creating a file using “system ‘touch abc’” also assign the right ownership. In my original script, calls to CVS also seem to be carried out with the right owner/group.
Running the command with su would be a possibility (I need some variables to be set prior to executing the command, so I use su -l rather than sudo), however I need to run it as a group (www) which isn’t the user’s primary group. I tried specifying the group with docu-user:www, but the system complains that the user doesn’t exist, and my su doesn’t have the -g option, so this doesn’t seem to be working. I’m looking into a solution on that front as well.

I wasn’t really aware of any difference, so I’m definitely going to look into this. This might actually change things as I noticed, following ab’s advice, that the environment variables “USER”, “LOGNAME” and “USERNAME” are still set to “root”, although the effective UID and GID are actually set to the values I chose. As I said, some commands seem to be working with simply the effective ID, but perhaps it’s not the case for all of them?..

That did work! :-))
Thx a lot, you saved my day! :slight_smile: