I am attempting to use sudo
to write to a file in /etc
that is writable only by root
, from inside an unprivileged C program.
system("sudo /bin/sh -c 'echo 'iface wlan0 inet dhcp' >> /etc/network/interfaces'");
This doesn't appear to fail, but the file is unmodified. What is wrong?
Structured as you have it, the redirection is evaluated outside the sudo
operation, and therefore does not have root privileges and cannot open /etc/network/interfaces
for writing. You need to do it like this instead:
system("sudo /bin/sh -c \"echo 'iface wlan0 inet dhcp' >> /etc/network/interfaces\"");
so that the redirection is evaluated by the shell inside the sudo.
(Also, you can't nest single quotes inside single quotes.)
For the sake of completeness, here is how I'd do that "the C way":
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void) {
const char string_to_append[] = "iface wlan0 inet dhcp\n";
size_t string_size;
FILE *fd;
/* Check for permissions */
if (getuid()) {
fprintf(stderr, "Run as root!\n");
return EXIT_FAILURE;
}
/* Now try to open the file for appending
* NOTE: fopen() will fail anyway if you dont have enough
* permissions to open this file with the specified mode,
* so the above check calling getuid() is somewhat redundant
*/
if ((fd = fopen("/etc/network/interfaces", "a")) == NULL) {
perror("Error opening file");
return EXIT_FAILURE;
}
/* Actual writing happens here */
string_size = strlen(string_to_append);
if (fwrite(string_to_append, sizeof(char), string_size, fd) != string_size) {
fprintf(stderr, "Error writing to file\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}