...
| Code Block | ||
|---|---|---|
| ||
#include <stdlib.h>
#include <unistd.h>
#include <libgen.h>
#include <sys/stat.h>
int secure_dir(const char* path) {
char *realpath_res = realpath(path, NULL);
char *path_copy = NULL;
char *dirname_res = NULL;
char ** dirs;
int num_of_dirs = 0;
int insecure = 0;
int i;
struct stat buf;
uid_t my_uid = getuid();
uid_t my_gid = getgid();
if (realpath_res == NULL) {
/* Handle Error */
}
if (!(path_copy = strdup(path))) {
/* Handle Error */
}
/* Figure out how far it is to the root */
while (1) {
dirname_res = dirname(path_copy);
free(path_copy);
path_copy = NULL;
num_of_dirs++;
if ((strcmp(dirname_res, ".") == 0)
|| (strcmp(dirname_res, "/") == 0)) {
break;
}
if (!(path_copy = strdup(dirname_res))) {
/* Handle Error */
}
}
free(path_copy);
path_copy = NULL;
/* Now allocate and fill the dirs array */
if (!(dirs = (char **) malloc(num_of_dirs*sizeof(*dirs)))) {
/* Handle Error */
}
if (!(dirs[num_of_dirs - 1] = strdup(path))) {
/* Handle Error */
}
if (!(path_copy = strdup(path))) {
/* Handle Error */
}
for (i = 1; i < num_of_dirs; i++) {
dirname_res = dirname(path_copy);
free(path_copy);
path_copy = NULL;
if (!(dirs[num_of_dirs - i - 1] = strdup(dirname_res))) {
/* Handle Error */
}
if (!(path_copy = strdup(dirname_res))) {
/* Handle Error */
}
}
free(path_copy);
path_copy = NULL;
/* Traverse from the root to the top, checking
* permissions along the way */
for (i = 0; i < num_of_dirs; i++) {
if (stat(dirs[i], &buf) != 0) {
/* Handle Error */
}
if (!((buf.st_uid == my_uid) || (buf.st_uid == 0)
||(buf.st_gid == my_gid) || (buf.st_gid == 0)
||(buf.st_mode & S_IRWXO))) {
/* Directory is owned or has a group other than root
* or file is accessible by other users */
insecure = -1;
}
free(dirs[i]);
dirs[i] = NULL;
}
free(dirs);
dirs = NULL;
return insecure;
}
|
...