-
change route
hello every1,
I need suggestion related change routing information from my program with user privileges. How I can change routing tables in my host linux or bsd based from user?
i.e. I launch my program with root, forked it and become use it with user privileges.
i.e2. I want make it more secure, therefore use user, but little bit stumbled about workable this situation.
-
The way other programs do this is to configure the port exactly as it needs to be, then demote yourself at run-time. This is assuming that you never need to change the configuration again. If this is the case, this is doable. Otherwise, perhaps you could fork() yourself and allow the parent to be the one that does the configuration, while the child (and its threads) answer all the calls to the outside world. The child would never have to have the higher privileges but would need to signal the parent when changes needed to be made (adding in an additional layer of security by adding in an additional layer).
-
In another words do full-trip pipe(or something else?) from parent to child(callback) and child to parent and as well as giving information to parent if that really needs? If that exact, then we could narrow bottleneck, but still use root privileges. I'm not use fork too much, usually pthread with shared-memory, because it more simple I think, then fork with signaling. anyway, how I can communicate parent and child instead of pipes or internal sockets?
-
I think you can still get shared memory via a couple of different functions, the easiest being:
Code:
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
I don't think you'll need a callback, just have a location in where you have an semaphore and a configuration struct that will allow you to change on the fly. Basically, you'll make your parent process sleep for most of the time. In fact, if you created a signal handler, your child could wake your parent whenever a change needed to be made (no need for a semaphore in this case).
I do not envy your task ahead.
-
I don't see why splitting the process is necessary. Just give yourself CAP_NET_ADMIN capability, then you can alter routing tables without needing to be root. Having a communication channel between an unprivileged and a privileged process seems scary to me. It's not an additional "layer of security," just another layer of complexity and potential bug-hiding place. An attack on your channel protocol could lead to unfettered root access. If you're so worried about coding errors that you're going to drop root access, what makes you think you won't make a coding error in your protocol?
Just drop all root privileges while retaining CAP_NET_ADMIN.
-
ok, I made this two ways. I've not too much data on follow, then I use just variables, instead of shared memory. Could you suggest to me something related architect this code.
Code:
=first=============
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
uid_t pw_uid
void
loop()
{
int s;
if (!capable(CAP_NET_ADMIN))
return 0;
s = socket(PF_INET, SOCK_DGRAM, 17);
// do everything from user
}
int
getusr()
{
struct passwd *ptr;
if ((ptr = getpwnam("user")) == NULL)
printf("getpwnam error\n");
return(ptr->pw_uid);
}
int
main(void)
{
getusr();
printf("before fork\n");
if ((pid = fork()) < 0){
printf("fork error\n");
return 0;
}else if (pid == 0) { /* child */
loop();
} else {
/* parent */
}
exit(0);
}
=second=============
--head.h
struct settings {
uint32_t ip;
};
--src1.c
int
getusr()
{
struct passwd *ptr;
if ((ptr = getpwnam("user")) == NULL)
printf("getpwnam error\n");
return(ptr->pw_uid);
}
int
main(void)
{
int fd, i, counter;
pid_t pid;
void *area;
int s;
struct settings *sx = 0;
struct sockaddr_in *sa;
// if ((fd = open("/dev/zero", O_RDWR)) < 0)
// err_sys("open error");
// if ((area = mmap(0, sizeof(long), PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0)) == MAP_FAILED)
// err_sys("mmap error");
// close(fd);
TELL_WAIT();
getusr();
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid > 0) { /* parent */
if(sx){
addr = sx->ip;
close(s);
}else{
s = socket(PF_INET, SOCK_DGRAM, 17);
addr = sa->sin_addr.s_addr;
}
if (bind_socket(s, addr) == -1) {
printf("bind_socket errot\n");
close(s);
return -1;
}
TELL_CHILD(pid);
WAIT_CHILD();
}
} else { /* child */
WAIT_PARENT();
loop();
}
exit(0);
}
--src2.c
extern struct settings *sx;
struct sockaddr_in *sa;
void loop(){
//todo smth.
if(sa->sin_addr.s_addr != &sx->ip)
TELL_PARENT(getppid()); // if I've got another ip-addres in settings struct and call parent.
}