• Post Reply Bookmark Topic Watch Topic
  • New Topic

Terminal (not Stdin Stdout) access through a session created by Runtime.exec()  RSS feed

 
Mal James
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Gang, Hope this is on-topic for the forum. About I/O specifically on Linux/Unix cmd line.

Some background:
A couple of years ago I wrote myself an object called CmdProc which runs any valid operating system command and tells me when it has finished, returning the relevant command output/results on demand. It uses Stdin, Stdout and Error and works quite nicely on Linux, AIX and Windows. So that is up-and-running and I have a reasonable understanding of how to access the three standard streams. With most OS commands I can retrieve the commands' prompts and respond (in Java) with further inputs. All working Ok.

Now I am trying to use this mechanism to run the "su" command on Unix.
My problem is that (from some obscure documentation that I have found) su reads its' input from the current terminal NOT from Stdin. So I need to modify my code to present text as if it had come from the current tty instead of from Stdin.

Anyone got any ideas as to how I do that? Or can supply a link to give some direction.

I have searched the forum for "terminal" but it seems to be generically used for stdin Etc. so I didn't find anything that looked hopeful.
I have tried some "ignorant fiddling" with the TERM environment variable and have discovered that when the command line session is launched from Runtime.exec I appear to get something called a pts rather than a tty (not too sure what the difference is but it seems to be related to terminal type). I have found something called /dev/tty which can be written to through a "real" command line session but doesn't exist when I try it through a session created via Runtime.exec.

Bit stuck now so TIA,
Mal
 
Tony Docherty
Bartender
Posts: 3271
82
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This may be more of a Unix problem than a Java one (or at least the solution may be Unix based rather than Java based) so I linking this to the Unix forum where you may get some better answers.
 
Mal James
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Tony. Makes sense. I didn't look deep enough to find the Linux/Unix forum.
 
Campbell Ritchie
Marshal
Posts: 56529
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So you only get that problem with Unix, not with Linux? What shells are you using?
I did a search and I have no idea whether this will be of any use to you.
 
Tim Holloway
Saloon Keeper
Posts: 18789
74
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, Campbell, that was for the "sudo" command, not "su". Big difference. Actually, I had to deduce it from the URL you posted. The actual link takes one nowhere useful since apparently it depended on your own machine's search context at the time it was captured.

Anyway, I think I can explain. No, this doesn't have to do with "pts", which, IIRC stands for something like "pseudo terminal service". Nor do you have to gain brute access to the /dev/tty device or whatever.

What it means - I think - is that "su" has the ability to set up an entire new shell context. Environment, stdin, stdout/err, and so forth. And this is what they're talking about. The stdin and stdout of the shell session where the "su" command was executed don't have to be the same as the stdin and stdout of the su-executed command. But if you have the right options in effect, they can be.

I setup a script just yesterday, in fact:


Note that the stdout redirect is outside the command in quotes. This was important, since the command was running as user "postgres", which doesn't have write access rights to the /archives/db backup directory. If I'd put the redirect within the quoted command context, I would have been denied access.

Incidentally, going back to "sudo", the sudo command mostly allows the same sort of execution contexts as "su" does (the cdrecord program being a notable exception). However as a rule, sudo is better. You can set up fine-grained access control for sudoers, limiting what commands they can execute. The "su" command has no such constraints, so - allowing for selinux - the "su" command allows you to commit total mayhem.
 
Campbell Ritchie
Marshal
Posts: 56529
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you. Explained far better than I could have.
 
Mal James
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Campbell - haven't actually tried to su in Linux yet. My initial need for that particular command is in AIX. But the CmdProc object has been running in Linux, Unix and Windows for a couple of years. Incidentally, I also had trouble following your link - something about ducks ??. But by chopping out the %2f inserts I found the sudo command. But I really want to set a session to the authority of a new user, not just run a single command.

Some background. Db2 task scheduler used to let us schedule batch jobs remotely under any userid through its' DAS protocol. But recently we moved to V10.5 and now have to use a userid that can SSH in to schedule the job. But some tasks (Eg. checking and pruning the diagnostic log and deleting old archive logs) require us to use the instance userid because Db2 creates the log file under that user with 600 permissions. So I need to submit the job under the SSH-enabled user but authorise several steps each of several lines with the instance userid. The Unix Admins don't want to grant the instance userids SSH because then the DBAs could use those ids directly (without having to use their own ids first) and no-one could tell who did what under the instance ids.

So thanks for your suggestion too Tim, but su -c also only runs a single command, rather than setting the session auth. This link says that su particularly gets its' password input from the terminal (/dev/tty) directly and I read somewhere that this is to avoid people being able to save their passwords in plain text and call su with redirected input.
I did spend some time thinking that su merely opens new stdIn and out streams and was looking for something like the ksh -i (or Windows cmd -i) which tells the shell to inherit current std streams. I used those in my cmdProc object. "su -i - userid" would have been nice......but there isn't one .

However, you appear to have cracked my problem!! If you scripted the code that you presented, how did you get the password input to su? 'cos that is all I am really trying to do; feed su a password from the java program controlling the shell. In java I can get the password from an encrypted file. And even with the -c option su still requires a password.
 
Tim Holloway
Saloon Keeper
Posts: 18789
74
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmmm. I'm not quite sure about what the best-practice approach would be here.

I use cron to run scheduled tasks under the DB2 instance user on one of my production systems, but I am Great High God of both the OS and DB2 so I can do any darned thing I please.

The system cron facility can run under any userid - in fact, it requires a userid. So that's one way to do it. But it does require that you be drinking buddies with both the database server's sysadmin and the db2 DBA. And that the database server be running Linux. Windows should have a task control equivalent, but I haven't touched Windows in a while. Except to do my taxes.

DAS is supposed to have been replaced with something better, so I'd first check with IBM and see what the "better" approach is. Unless you're actually meddling with filesystem-level stuff or other externals (my cron scripts run theserver's hot backups), then it's usually preferable to use DB2 stored procedures to do your work and avoid the shell environment entirely.

As far as "su" goes, I don't have to worry about passwords, since the script in question runs under cron as root. Like I said, I'm God, so I have the option to do so. The reason cron runs it as root is that it's actually backing up different database products, each of which interacts under a different userID.

I do recommend that when invoking external programs you use scripts instead of raw commands, though. It's easier to insert debugging statements plus, of course, the command sequence can be as simple or as complex as you need.

 
Mal James
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks again to all who contributed - it is much appreciated.
The answer - or at least, an answer for now - seems to be to install send/expect on the Unix box. Then I can create a send/expect script on the fly in Java and call it with the decrypted password as the parm. Irritatingly specific to Unix boxes with send/expect installed so not a complete answer. Hopefully I will find time soon to browse the send/expect source code in Tcl and see if there is a way in Java to do the same as it does. Send/expect manages to push the password into sus' input stream so there must be a way.
 
Mal James
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Again, just to close off this topic.
The send/expect solution worked but was not a success due to vast amounts of "control" characters suddenly appearing in the output (^M being the most prevalent) and totally messing up all previous formatting and mailings from the jobs that were run through this mechanism. This comes from Tcl apparently.

Eventually we allowed our "batch" userid to sudo "nopasswd" to the instance userids but only to use specific DB2 libraries and java.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!