UbixOS  2.0
namei.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2002-2018 The UbixOS Project.
3  * All rights reserved.
4  *
5  * This was developed by Christopher W. Olsen for the UbixOS Project.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  *
10  * 1) Redistributions of source code must retain the above copyright notice, this list of
11  * conditions, the following disclaimer and the list of authors.
12  * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13  * conditions, the following disclaimer and the list of authors in the documentation and/or
14  * other materials provided with the distribution.
15  * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16  * endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/types.h>
30 #include <ubixos/errno.h>
31 #include <vfs/vfs.h>
32 #include <ubixos/sched.h>
33 
34 int follow_link(struct inode * dir, struct inode * inode, int flag, int mode, struct inode ** res_inode) {
35 
36  if (!dir || !inode) {
37  iput(dir);
38  iput(inode);
39  *res_inode = NULL;
40  return -ENOENT;
41  }
42 
43  if (!inode->i_op || !inode->i_op->follow_link) {
44  iput(dir);
45  *res_inode = inode;
46  return 0;
47  }
48 
49  return inode->i_op->follow_link(dir, inode, flag, mode, res_inode);
50 }
51 
52 int permission(struct inode * inode, int mask) {
53  int mode = inode->i_mode;
54 
55  if (inode->i_op && inode->i_op->permission)
56  return inode->i_op->permission(inode, mask);
57  else if (_current->euid == inode->i_uid)
58  mode >>= 6;
59  else if (in_group_p(inode->i_gid))
60  mode >>= 3;
61 
62  if (((mode & mask & 0007) == mask)) // || suser())
63  return 1;
64 
65  return 0;
66 }
67 
68 int lookup(struct inode * dir, const char * name, int len, struct inode ** result) {
69  struct super_block * sb;
70  int perm;
71 
72  *result = NULL;
73 
74  if (!dir)
75  return -ENOENT;
76 
77  /* check permissions before traversing mount-points */
78  perm = permission(dir, MAY_EXEC);
79 
80  if (len == 2 && name[0] == '.' && name[1] == '.') {
81 
82 #ifdef _IGNORE
83  if (dir == _current->root) {
84  *result = dir;
85  return 0;
86  }
87  else if ((sb = dir->i_sb) && (dir == sb->s_mounted)) {
88  sb = dir->i_sb;
89  iput(dir);
90  dir = sb->s_covered;
91  if (!dir)
92  return -ENOENT;
93  dir->i_count++;
94  }
95 #endif
96 
97  }
98 
99  if (!dir->i_op || !dir->i_op->lookup) {
100  iput(dir);
101  return -ENOTDIR;
102  }
103 
104  if (!perm) {
105  iput(dir);
106  return -EACCES;
107  }
108 
109  if (!len) {
110  *result = dir;
111  return 0;
112  }
113 
114  return dir->i_op->lookup(dir, name, len, result);
115 }
116 
117 static int dir_namei(const char * pathname, int * namelen, const char ** name, struct inode * base, struct inode ** res_inode) {
118  char c;
119  const char *thisname;
120  int len;
121  int error;
122  struct inode *inode;
123 
124  *res_inode = NULL;
125 
126 #ifdef _IGNORE
127  if (!base) {
128  base = _current->pwd;
129  base->i_count++;
130  }
131 #endif
132 
133  if (!base) {
134  kprintf("BASE == NULL");
135  }
136 
137  if ((c = *pathname) == '/') {
138  iput(base);
139 #ifdef _IGNORE
140  base = _current->root;
141 #endif
142  pathname++;
143  base->i_count++;
144  }
145 
146  while (1) {
147  thisname = pathname;
148  for (len = 0; (c = *(pathname++)) && (c != '/'); len++)
149  /* nothing */;
150  if (!c)
151  break;
152  base->i_count++;
153  error = lookup(base, thisname, len, &inode);
154  if (error) {
155  iput(base);
156  return error;
157  }
158  error = follow_link(base, inode, 0, 0, &base);
159  if (error)
160  return error;
161  }
162  if (!base->i_op || !base->i_op->lookup) {
163  iput(base);
164  return -ENOTDIR;
165  }
166  *name = thisname;
167  *namelen = len;
168  *res_inode = base;
169  return 0;
170 }
171 
172 int namei(const char * pathname, struct inode * base, int follow_links, struct inode ** res_inode) {
173  const char *basename;
174  int namelen, error;
175  struct inode *inode;
176 
177  *res_inode = NULL;
178 
179  error = dir_namei(pathname, &namelen, &basename, base, &base);
180  if (error)
181  return error;
182 
183  base->i_count++; /* lookup uses up base */
184 
185  error = lookup(base, basename, namelen, &inode);
186 
187  if (error) {
188  iput(base);
189  return error;
190  }
191 
192  if (follow_links) {
193  error = follow_link(base, inode, 0, 0, &inode);
194  if (error)
195  return error;
196  }
197  else
198  iput(base);
199 
200  *res_inode = inode;
201 
202  return 0;
203 }
iput
void iput(struct inode *inode)
Definition: inode.c:47
inode::i_sb
struct super_block * i_sb
Definition: inode.h:55
taskStruct::euid
uint16_t euid
Definition: sched.h:74
inode::i_uid
uid_t i_uid
Definition: inode.h:44
vfs.h
lookup
int lookup(struct inode *dir, const char *name, int len, struct inode **result)
Definition: namei.c:68
super_block
Definition: vfs.h:107
inode::i_count
unsigned short i_count
Definition: inode.h:64
inode::i_gid
gid_t i_gid
Definition: inode.h:45
sched.h
types.h
ENOTDIR
#define ENOTDIR
Definition: errno.h:53
inode
Definition: inode.h:39
inode_operations::follow_link
int(* follow_link)(struct inode *, struct inode *, int, int, struct inode **)
Definition: vfs.h:85
follow_link
int follow_link(struct inode *dir, struct inode *inode, int flag, int mode, struct inode **res_inode)
Definition: namei.c:34
super_block::s_covered
struct inode * s_covered
Definition: vfs.h:118
_current
kTask_t * _current
Definition: sched.c:50
name
const char * name
Definition: pci.c:37
inode_operations::permission
int(* permission)(struct inode *, int)
Definition: vfs.h:88
inode::i_mode
__mode_t i_mode
Definition: inode.h:42
inode_operations::lookup
int(* lookup)(struct inode *, const char *, int, struct inode **)
Definition: vfs.h:76
taskStruct::pwd
struct inode * pwd
Definition: sched.h:80
inode::i_op
struct inode_operations * i_op
Definition: inode.h:54
ENOENT
#define ENOENT
Definition: errno.h:33
taskStruct::root
struct inode * root
Definition: sched.h:81
MAY_EXEC
#define MAY_EXEC
Definition: vfs.h:39
kprintf
int kprintf(const char *,...)
Definition: kprintf.c:259
errno.h
namei
int namei(const char *pathname, struct inode *base, int follow_links, struct inode **res_inode)
Definition: namei.c:172
super_block::s_mounted
struct inode * s_mounted
Definition: vfs.h:119
in_group_p
int in_group_p(gid_t grp)
Definition: access.c:76
EACCES
#define EACCES
Definition: errno.h:45
permission
int permission(struct inode *inode, int mask)
Definition: namei.c:52
NULL
#define NULL
Definition: fat_string.h:17