libcfe  0.12.1
some useful C-functions
check_path_exists.c
Go to the documentation of this file.
1 #include "config.h"
2 #include "check_path_exists.h"
3 
4 #include <stdlib.h>
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 #include <unistd.h>
8 
9 #define perm_owner(m) ((m & S_IRWXU) >> 6)
10 #define perm_group(m) ((m & S_IRWXG) >> 3)
11 #define perm_other(m) (m & S_IRWXO)
12 #define check_mode(m, c) (((m) | (c)) == (m) ? 1 : 0)
13 #define checkpermission_root(m, c) check_mode(perm_owner(m) | perm_group(m) | perm_other(m), c)
14 
15 int read_all_groups(gid_t **g);
16 int checkpermission(struct stat *st, mode_t mode);
17 
18 int read_all_groups(gid_t **g)
19 {
20  int ngroups = getgroups(0, NULL);
21  gid_t *groups = (gid_t *)realloc(*g, ngroups * sizeof(gid_t));
22  if(getgroups(ngroups, groups) < 0)
23  {
24  free(groups);
25  groups = NULL;
26  ngroups = 0;
27  }
28  *g = groups;
29  return ngroups;
30 }
31 
32 int checkpermission(struct stat *st, mode_t mode)
33 {
34  uid_t uid = geteuid();
35  if(uid == 0) /* if the program runs as root, file permissions can be (bitwise) sumerized. */
36  return checkpermission_root(st->st_mode, mode);
37  else if(uid == st->st_uid) /* the program and the file have the same owner, check the owner permissions. */
38  return check_mode(perm_owner(st->st_mode), mode);
39 
40  /* the uid of the program is not 0 and does not match the uid of the file, now check for a machting group. */
41  gid_t *gid = NULL;
42  int i, ngid = read_all_groups(&gid); /* get all groups the program is in. */
43  for(i = 0; i < ngid; i++)
44  {
45  if(gid[i] == st->st_gid)
46  { /* there is a match between the program and file group */
47  free(gid); /* free the memory, because we will return. */
48  gid = NULL;
49  /* check the group permissions. */
50  return check_mode(perm_group(st->st_mode), mode);
51  }
52  }
53  free(gid);
54  gid = NULL;
55 
56  /* there is no match with the owner and group of the file, check the permissions for others */
57  return check_mode(perm_other(st->st_mode), mode);
58 }
59 
60 int check_path_exists(const char *path, mode_t type, mode_t mode)
61 {
62  struct stat st;
63 
64  if(stat(path, &st) != 0) /* cannot get file attributes, assume that the file does not exists */
65  return -1;
66 
67  /* check the file type. */
68  if(!check_mode(st.st_mode & S_IFMT, type))
69  return -1;
70 
71  /* check the file permission, only if 'mode' is not 0. */
72  if(mode != 0 && !checkpermission(&st, mode))
73  return -1;
74 
75  return 0;
76 }
#define perm_group(m)
int checkpermission(struct stat *st, mode_t mode)
#define check_mode(m, c)
#define perm_owner(m)
int check_path_exists(const char *path, mode_t type, mode_t mode)
#define perm_other(m)
int read_all_groups(gid_t **g)
#define checkpermission_root(m, c)