Set display before indicate path into (execlp) - c

I need to work with multiple displays in execlp calls (). I'm trying this:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("calling to execlp:\n\n");
execlp("DISPLAY=:0 /usr/bin/qtdisplay","qtdisplay", "-r", NULL);
execlp("DISPLAY=:1 /usr/bin/qtdisplay","qtdisplay", "-r", NULL);
printf("fail!");
exit(0);
}
But this fails, with the following message: execlp: No such file or directory
Is there any way to work with the displays?

Try system() instead, it'll start a new child process and call exec() from there. Also, it handles shell command-line constructs by calling a shell and handing your shell construct to that shell, like this:
system("DISPLAY=:0; /usr/bin/qtdisplay -r");
Also, learn to check return codes from functions like this, and do some sane action (like print an error message):
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int rc;
rc = system("DISPLAY=:0; /usr/bin/qtdisplay -r");
if (rc == -1) {
perror("error starting qtdisplay on :0");
exit(1);
}
rc = system("DISPLAY=:1; /usr/bin/qtdisplay -r");
if (rc == -1) {
perror("error starting qtdisplay on :1");
exit(1);
}
exit(0);
}
If you want these two commands to be run in parallel (not one after the other), you should use command-lines like this:
system("DISPLAY=:0; /usr/bin/qtdisplay -r &");

Related

C exec multi commands

i am struggling and your input would be really appreciated. i'm trying to chain arguments to the command line using exec and an array to hold the arguments. the problem comes when I try to chain more than one command. tried using an ";" to separate each command but that does not seem to be working.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>enter code here
int main(){
int proc1 = fork();
char*myargv[16];
myargv[0]="/bin/ls";
myargv[1]="-F;";
myargv[2]="pwd";
myargv[3]=NULL;
if(proc1==0){
execve(myargv[0],myargv,NULL);
exit(1);
}else{
wait(NULL);
printf("This wlways last");
}
return 0;
}

How to call shell commands on bin/sh opened through execl

In my code, I am using execve() to execute a file at a particular location.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define FILE "newFolder/program"
int main() {
char *n[] = { FILE, NULL };
execve(FILE, n, NULL);
perror("execve");
exit(1);
}
I do not have the complete source code of FILE but I know that it ends in the following:
execl("/bin/sh", "/bin/sh", NULL);
Is there a way for me, through my code which calls FILE, to execute shell commands (i.e. ls -la) on the bin/sh that FILE opened?

Why after load seccomp filter, PING will no work by normal user

I use seccomp record 'ping' used syscall. When I run it, it always notice
socket: Operation not permitted.
I can run ping in bash very well, but no work after load seccomp filter in program.
But if I run the same program by root, it will run very well.
This is running in Ubuntu 18.04 with 4.15.0-54-generic kernel.
I have tried use Root user to run the program, then in the child progress, I use setuid(1000) to set to a normal user, and it still no work.
If I not use fork, it still notice no premitted.
If I change the seccomp default action to SCMP_ACT_ALLOW, it still no work too.
Here is a simple code by C.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <signal.h>
#include <seccomp.h>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/wait.h>
void child() {
setuid(1000);
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_LOG);
if (seccomp_load(ctx) != 0) {
printf("SCMP LAOD ERR!");
} else {
seccomp_release(ctx);
}
execl("/bin/ping", "ping", "-c", "1", "172.16.1.1", NULL);
printf("EXEC FAIL");
}
int main(){
int p = fork();
if (p < 0) {
printf("Frok ERROR!");
exit(1);
}
if ( p == 0 ) {
child();
} else {
struct rusage usage;
int status;
if (wait4(p, &status, WSTOPPED, &usage) == -1) {
kill(p, SIGKILL);
}
}
}
I use gcc main.c -o main.out -lseccomp to compile it.
English is not my first Language, I'm sorry about my grammar.
ping only works as root. Normally it runs as root because it has the setuid bit set in its file permissions:
-rwsr-xr-x 1 root root 44168 May 8 2014 /bin/ping
^ ^^^^
|
this 's' is called 'setuid' and means it wants to run as the user which owns it, which is root
You cannot use seccomp unless you are root, or you set the no_new_privs flag. You are not using seccomp directly, but through a library. It appears the library is setting the flag for you.
The no_new_privs flag means that you cannot run setuid programs. Well, you can run them, but they won't be setuid. They'll run as your user. Which doesn't have permission to send special packets the way ping requires. So ping fails because it doesn't have permission to ping.

How do I prevent a library to print to stdout (in Linux/C)?

I am using a library that prints all kind of crappy messages to stdout. I try to keep a clean output on my program, but that makes it impossible.
Any idea?
You can close() the stdout socket and then open a new socket to /dev/null (assuming pretty much anything but windows here).
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int newfd;
printf("good things come...\n");
close(1);
newfd = open("/dev/null", O_WRONLY);
if (newfd != 1) {
fprintf(stderr, "uh oh... we didn't duplicate the socket properly\n");
exit(1);
}
printf("...to those that wait()\n");
}
And then running this you get:
$ ./test
good things come...
Note the no final line from printf.
[but I agree with the comments: using libraries that show signs of bad-things is probably a bad-choice for other reasons beyond the first one you spot]

seteuid() not working. Reason?

I'm completely new to C and I use it very rarely. This time i need it for a university project. I have to write a small c app that tests some modifications we made on the Linux kernel (on the scheduler).
Inside the script I'd like to switch to another user to see the distribution of CPU times among the different users. So I start my small C prog with root rights (i.e. with sudo ./myapp). Inside the prog - after I performed some operations which need root rights - I would like to switch back to another uid by calling seteuid(1000) or setuid(1000) where 1000 is the ID of an existing user (the one I used to log on). However the call doesn't seem to have any effect, it doesn't throw any exception neither.
Here's a sample I wrote, just to test the uid switching:
#define _POSIX_SOURCE
#include <pwd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <unistd.h>
#include <string>
#include <time.h>
using namespace std;
int main(int argc, char *argv[])
{
int uid;
struct passwd *p;
if ((p = getpwuid(uid = getuid())) == NULL){
perror("getpwuid() error");
exit(1);
}
printf("***************************************\n");
printf("Executing user: %s (%d)\n", p->pw_name, p->pw_uid);
printf("***************************************\n");
seteuid(1000);
if ((p = getpwuid(uid = getuid())) == NULL){
perror("getpwuid() error");
exit(1);
}
printf("***************************************\n");
printf("Executing user: %s (%d)\n", p->pw_name, p->pw_uid);
printf("***************************************\n");
return 0;
}
Does anyone know why it won't work?? Any help is highly appreciated! Thx
//Edit:
Corrected code as mentioned by chsh
I think it is working just fine, there's just a problem with the logic in the code because you're capturing the value of getuid() into the passwd struct, and then just displaying it twice without retrieving it again after calling seteuid().

Resources