I'm calling a c program using crontab.
If I call the program directly, everything is fine.
If the program is called by cron, my .log files can't be opened.
the program is in a directory
/stuff1/stuff2/stuff3/program
all pathnames in the program are absolute
just to make sure, I chmod 777'd everything in stuff3
EDIT:
The line from crontab is
0 * * * * /stuff1/stuff2/stuff3/program
EDIT2:
Issue isn't with cron, if I run it like this
cd /
/stuff1/stuff2/stuff3/program
it fails
if I run it like this:
cd /stuff1/stuff2/stuff3/program
program
everything is peachy.
What does linux change that could affect my program when run in those two different ways?
This'll probably help you get to the bottom of it, since you know at least some C:
http://stromberg.dnsalias.org/~strombrg/debugging-with-syscall-tracers.html
The problem was that the program I was forking was attempting to write to ./
This caused permission failures as cron doesn't run the program from the directory it is in, rather it runs it from some other directory that I didn't have write permissions in.
Related
Essentially, I wish to call compiled C code from inside a bash script. I want to be able to call the ./a.out from any directory and have it be executed.
This all stems from something pretty simple. I made a curses program that is a screensaver for a terminal. I wish to be able to call a bash command screensaver and I want that to call the c code via bash. I want to be able to call it from anywhere in the filesystem. I am running on a 2013 Macbook but I think this is more of an infamiliarity with C issue rather than a hardware issue, I can provide more details if needed.
File is here:
/Users/User/screensaver/screensaver.c
cd /Users/User/screensaver
gcc screensaver.c creates a.out
I can then run
./a.out
And the code runs.
I have tried calling ./Users/User/screensaver/a.out among other things.
This doesn't work and it just says that the file doesn't exist. I've tried using exec and source but nothing has worked. Surely there must be a way to call this from somewhere else right? I know I could theoretically save my current directory as an environment variable, cd into the dir, ./a.out, then on quit cd back into the saved dir, but that seems like to much struggle for what its worth.
Edit: I saw that I could theoretically put it in the my bin and compiled with -o. I haven't tried it, but I don't want to do that because this code is still in development so I don't want to have to compiled and move it every time.
This worked:
"Try to invoke /Users/User/screensaver/a.out without putting a dot at the beginning of the path. There is a paticular security reason why you need to specify ./a.out rather than a.out when you are in the directory which holds the executable."
-tshiono
In my source code I make chroot and then have some code doing some staff then I want to execute linux command. But the command does not work since I changed the root with chroot.
here after the source code:
int main(void)
{
if (chroot("/tmp") < 0)
printf("error in chroot\n");
/* some source code doing staffs */
system("ls > /logloglog.txt"); // command failed
return 0;
}
How to execute command in chroot?
Or is it possible to exit from chrood then execute the command and then back to the chroot again?
If you use chroot(), you have to consider the consequences of what you do. One of the major consequences is that many (most, all) of the commands normally available are not available unless you make them available in the chroot()'d environment.
Doing that job properly is non-trivial. You may need parts of /dev, /bin, /etc, /usr, /lib (and probably others too) installed appropriately under the new root directory. Symlinks back to 'outside the chroot() environment' won't work, in general. You have to make copies of what's important. One side effect of all this: /tmp is very rarely an appropriate place to create a fully operational chroot() environment. You might get away with a limited access sub-directory under /tmp, but putting a user in /tmp doesn't isolate them from other users, or other users from them, very well.
One other major possibility: you do not give the user access to other commands after you've done chroot(). That is, you do not try to use system() in your code; and you don't give the victim user access to a shell or shell utilities.
Using chroot() is not something you do casually, in other words. To do a good job takes quite a lot of careful thought and preparation.
Would you be better off with a container or virtual machine of some sort instead?
Do use Google or any other search engine to search for terms such as:
'chroot jail escape'
'chroot jail setup'
'chroot jail vs docker'
Is it possible to exit from chroot then execute the command and then back to the chroot again?
Not really. You might be able have a controlling program that forks a child that does chroot() and processes material and then terminates, so that the controlling program can do its job (execute the command) and then you could fork another child that goes back into the chroot() jail. But that's not the same as the current process getting out of jail — it would make chroot() totally ineffective if any program could cancel its jail time on a whim and resume unjailed activity.
What about:
system("chroot /tmp /bin/bash -c \"<COMMAND>\"");
You can just run chroot using system directly and with -c execute command inside /tmp environment
So, I am working on an application that reads files, much the way vim or cat would, where you type "appname /path/to/file.txt" and it passes the file path as a perameter to the program which manipulates the file in some way.
I have run into a roadblock though. In vim, cat, or a similar program, you can type "appname file.txt", and it will read the file in the current directory that you launch the application from terminal in.
For example, I want to edit a file my documents directory. I type "cd ~/Documents", and then I can either type "vim ~/Documents/Essay.txt", or I just can type "vim Essay.txt".
My application will be stored in a binary file in the /bin/ directory so I can launch it from anywhere using the Terminal, but how do I pass the path name of the directory I am in when I call it from terminal?
As I am a new Linux developer (I have always worked with the .NET launguages in Windows) I am not sure weather this is handled by the Linux terminal, or by the C application itself.
Any help or suggestions would be much appreciated!
Also, if there is a more efficiant way to run it from the terminal than sticking it in the /bin/, let me know.
If you want to get the directory the process was run from you can use the system call getcwd to copy a string into a buffer and return it. The kernel keeps track of this for every process.
e.g.
char buf[100];
printf("Current directory: %s\n", getcwd(buf, 100));
The working directory can be changed, but will default to where the process launched.
This should work just fine without you having to do anything special. Did you try something that didn't work as you expected?
Generally you don't put user programs in /bin. I would store your program in /usr/local/bin.
https://unix.stackexchange.com/a/8658
My C program (on Linux) needs to delete a file, say, /home/me/myfile, here is how I do it in my program
...
system ("rm -f /home/me/myfile");
...
When running this program, I got a message saying permission denied. BTW, ls -al /home/me/myfile returns -rw-r--r--
However, under the same user account and in the same shell I execute the C program, I can simple delete the file by typing rm -f /home/me/myfile
What did I miss here?
Thanks,
Update: Using remove(/home/me/myfile) or unlink(/home/me/myfile), the file can be deleted in my program.
For a start, it's the permissions on the directory that control whether you can delete a file.
But, having said that, there are numerous things that could be different between the two situations. Your program might be running as a different user (such as with the SETUID bit), the path may be different, leading to a different rm being run, the program may set up a chroot jail so that it can no longer even see the file (though that may manifest as a different error), and so forth. The possibilities are rather large.
However, C provides a call to delete files, called unlink - you should use that in preference and then check errno.
I would suggest checking the output of which rm in both cases, along with the full details of the file and executable, owner and permissions.
This is the command I'm using:
rsync --partial --timeout=60 --rsh='/usr/bin/ssh -i /root/.ssh/id_rsa' /path/file user#host:/remote_path/
This works when I run it on the command line, but does not work when I use system() in my C program.
Correction: This call will not work after boot up, no matter how long the program runs. If the program is restarted it will work every time no matter how many times the program is run.
status = system("rsync --partial --timeout=60 --rsh='/usr/bin/ssh -i /root/.ssh/id_rsa' /path/file user#host:/remote_path/");
The return value from rsync is 12: Error in rsync protocol data stream.
Turns out that the problem was the environment variables. HOME was set to '/' on start up instead of '/user'. ssh was unable to locate the known_hosts file and therefor the auto-login failed, causing rsync to fail.