This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / kernel / ckrm / rbce / token.c
1 #include <linux/parser.h>
2 #include <linux/ctype.h>
3
4 enum rule_token_t {
5         TOKEN_PATH,
6         TOKEN_CMD,
7         TOKEN_ARGS,
8         TOKEN_RUID_EQ,
9         TOKEN_RUID_LT,
10         TOKEN_RUID_GT,
11         TOKEN_RUID_NOT,
12         TOKEN_RGID_EQ,
13         TOKEN_RGID_LT,
14         TOKEN_RGID_GT,
15         TOKEN_RGID_NOT,
16         TOKEN_EUID_EQ,
17         TOKEN_EUID_LT,
18         TOKEN_EUID_GT,
19         TOKEN_EUID_NOT,
20         TOKEN_EGID_EQ,
21         TOKEN_EGID_LT,
22         TOKEN_EGID_GT,
23         TOKEN_EGID_NOT,
24         TOKEN_XID_EQ,
25         TOKEN_XID_LT,
26         TOKEN_XID_GT,
27         TOKEN_XID_NOT,
28         TOKEN_TAG,
29         TOKEN_IPV4,
30         TOKEN_IPV6,
31         TOKEN_DEP,
32         TOKEN_DEP_ADD,
33         TOKEN_DEP_DEL,
34         TOKEN_ORDER,
35         TOKEN_CLASS,
36         TOKEN_STATE,
37         TOKEN_INVALID
38 };
39
40 int token_to_ruleop[TOKEN_INVALID + 1] = {
41         [TOKEN_PATH] = RBCE_RULE_CMD_PATH,
42         [TOKEN_CMD] = RBCE_RULE_CMD,
43         [TOKEN_ARGS] = RBCE_RULE_ARGS,
44         [TOKEN_RUID_EQ] = RBCE_RULE_REAL_UID,
45         [TOKEN_RUID_LT] = RBCE_RULE_REAL_UID,
46         [TOKEN_RUID_GT] = RBCE_RULE_REAL_UID,
47         [TOKEN_RUID_NOT] = RBCE_RULE_REAL_UID,
48         [TOKEN_RGID_EQ] = RBCE_RULE_REAL_GID,
49         [TOKEN_RGID_LT] = RBCE_RULE_REAL_GID,
50         [TOKEN_RGID_GT] = RBCE_RULE_REAL_GID,
51         [TOKEN_RGID_NOT] = RBCE_RULE_REAL_GID,
52         [TOKEN_EUID_EQ] = RBCE_RULE_EFFECTIVE_UID,
53         [TOKEN_EUID_LT] = RBCE_RULE_EFFECTIVE_UID,
54         [TOKEN_EUID_GT] = RBCE_RULE_EFFECTIVE_UID,
55         [TOKEN_EUID_NOT] = RBCE_RULE_EFFECTIVE_UID,
56         [TOKEN_EGID_EQ] = RBCE_RULE_EFFECTIVE_GID,
57         [TOKEN_EGID_LT] = RBCE_RULE_EFFECTIVE_GID,
58         [TOKEN_EGID_GT] = RBCE_RULE_EFFECTIVE_GID,
59         [TOKEN_EGID_NOT] = RBCE_RULE_EFFECTIVE_GID,
60         [TOKEN_XID_EQ]  = RBCE_RULE_XID,
61         [TOKEN_XID_LT]  = RBCE_RULE_XID,
62         [TOKEN_XID_GT]  = RBCE_RULE_XID,
63         [TOKEN_XID_NOT] = RBCE_RULE_XID,
64         [TOKEN_TAG] = RBCE_RULE_APP_TAG,
65         [TOKEN_IPV4] = RBCE_RULE_IPV4,
66         [TOKEN_IPV6] = RBCE_RULE_IPV6,
67         [TOKEN_DEP] = RBCE_RULE_DEP_RULE,
68         [TOKEN_DEP_ADD] = RBCE_RULE_DEP_RULE,
69         [TOKEN_DEP_DEL] = RBCE_RULE_DEP_RULE,
70         [TOKEN_ORDER] = RBCE_RULE_INVALID,
71         [TOKEN_CLASS] = RBCE_RULE_INVALID,
72         [TOKEN_STATE] = RBCE_RULE_INVALID,
73 };
74
75 enum op_token {
76         TOKEN_OP_EQUAL = RBCE_EQUAL,
77         TOKEN_OP_NOT = RBCE_NOT,
78         TOKEN_OP_LESS_THAN = RBCE_LESS_THAN,
79         TOKEN_OP_GREATER_THAN = RBCE_GREATER_THAN,
80         TOKEN_OP_DEP,
81         TOKEN_OP_DEP_ADD,
82         TOKEN_OP_DEP_DEL,
83         TOKEN_OP_ORDER,
84         TOKEN_OP_CLASS,
85         TOKEN_OP_STATE,
86 };
87
88 enum op_token token_to_operator[TOKEN_INVALID + 1] = {
89         [TOKEN_PATH] = TOKEN_OP_EQUAL,
90         [TOKEN_CMD] = TOKEN_OP_EQUAL,
91         [TOKEN_ARGS] = TOKEN_OP_EQUAL,
92         [TOKEN_RUID_EQ] = TOKEN_OP_EQUAL,
93         [TOKEN_RUID_LT] = TOKEN_OP_LESS_THAN,
94         [TOKEN_RUID_GT] = TOKEN_OP_GREATER_THAN,
95         [TOKEN_RUID_NOT] = TOKEN_OP_NOT,
96         [TOKEN_RGID_EQ] = TOKEN_OP_EQUAL,
97         [TOKEN_RGID_LT] = TOKEN_OP_LESS_THAN,
98         [TOKEN_RGID_GT] = TOKEN_OP_GREATER_THAN,
99         [TOKEN_RGID_NOT] = TOKEN_OP_NOT,
100         [TOKEN_EUID_EQ] = TOKEN_OP_EQUAL,
101         [TOKEN_EUID_LT] = TOKEN_OP_LESS_THAN,
102         [TOKEN_EUID_GT] = TOKEN_OP_GREATER_THAN,
103         [TOKEN_EUID_NOT] = TOKEN_OP_NOT,
104         [TOKEN_EGID_EQ] = TOKEN_OP_EQUAL,
105         [TOKEN_EGID_LT] = TOKEN_OP_LESS_THAN,
106         [TOKEN_EGID_GT] = TOKEN_OP_GREATER_THAN,
107         [TOKEN_EGID_NOT] = TOKEN_OP_NOT,
108         [TOKEN_XID_EQ]  = TOKEN_OP_EQUAL,
109         [TOKEN_XID_LT]  = TOKEN_OP_LESS_THAN,
110         [TOKEN_XID_GT]  = TOKEN_OP_GREATER_THAN,
111         [TOKEN_XID_NOT] = TOKEN_OP_NOT,
112         [TOKEN_TAG] = TOKEN_OP_EQUAL,
113         [TOKEN_IPV4] = TOKEN_OP_EQUAL,
114         [TOKEN_IPV6] = TOKEN_OP_EQUAL,
115         [TOKEN_DEP] = TOKEN_OP_DEP,
116         [TOKEN_DEP_ADD] = TOKEN_OP_DEP_ADD,
117         [TOKEN_DEP_DEL] = TOKEN_OP_DEP_DEL,
118         [TOKEN_ORDER] = TOKEN_OP_ORDER,
119         [TOKEN_CLASS] = TOKEN_OP_CLASS,
120         [TOKEN_STATE] = TOKEN_OP_STATE
121 };
122
123 static match_table_t tokens = {
124         {TOKEN_PATH, "path=%s"},
125         {TOKEN_CMD, "cmd=%s"},
126         {TOKEN_ARGS, "args=%s"},
127         {TOKEN_RUID_EQ, "uid=%d"},
128         {TOKEN_RUID_LT, "uid<%d"},
129         {TOKEN_RUID_GT, "uid>%d"},
130         {TOKEN_RUID_NOT, "uid!%d"},
131         {TOKEN_RGID_EQ, "gid=%d"},
132         {TOKEN_RGID_LT, "gid<%d"},
133         {TOKEN_RGID_GT, "gid>%d"},
134         {TOKEN_RGID_NOT, "gid!d"},
135         {TOKEN_EUID_EQ, "euid=%d"},
136         {TOKEN_EUID_LT, "euid<%d"},
137         {TOKEN_EUID_GT, "euid>%d"},
138         {TOKEN_EUID_NOT, "euid!%d"},
139         {TOKEN_EGID_EQ, "egid=%d"},
140         {TOKEN_EGID_LT, "egid<%d"},
141         {TOKEN_EGID_GT, "egid>%d"},
142         {TOKEN_EGID_NOT, "egid!%d"},
143         {TOKEN_XID_EQ,  "xid=%d"},
144         {TOKEN_XID_LT,  "xid<%d"},
145         {TOKEN_XID_GT,  "xid>%d"},
146         {TOKEN_XID_NOT, "xid!%d"},
147         {TOKEN_TAG, "tag=%s"},
148         {TOKEN_IPV4, "ipv4=%s"},
149         {TOKEN_IPV6, "ipv6=%s"},
150         {TOKEN_DEP, "depend=%s"},
151         {TOKEN_DEP_ADD, "+depend=%s"},
152         {TOKEN_DEP_DEL, "-depend=%s"},
153         {TOKEN_ORDER, "order=%d"},
154         {TOKEN_CLASS, "class=%s"},
155         {TOKEN_STATE, "state=%d"},
156         {TOKEN_INVALID, NULL}
157 };
158
159 /*
160  * return -EINVAL in case of failures
161  * returns number of terms in terms on success.
162  * never returns 0.
163  */
164
165 static int
166 rules_parse(char *rule_defn, struct rbce_rule_term **rterms, int *term_mask)
167 {
168         char *p, *rp = rule_defn;
169         int option, i = 0, nterms;
170         struct rbce_rule_term *terms;
171
172         *rterms = NULL;
173         *term_mask = 0;
174         if (!rule_defn)
175                 return -EINVAL;
176
177         nterms = 0;
178         while (*rp++) {
179                 if (*rp == '>' || *rp == '<' || *rp == '=') {
180                         nterms++;
181                 }
182         }
183
184         if (!nterms) {
185                 return -EINVAL;
186         }
187
188         terms = kmalloc(nterms * sizeof(struct rbce_rule_term), GFP_KERNEL);
189         if (!terms) {
190                 return -ENOMEM;
191         }
192
193         while ((p = strsep(&rule_defn, ",")) != NULL) {
194
195                 substring_t args[MAX_OPT_ARGS];
196                 int token;
197
198                 while (*p && isspace(*p))
199                         p++;
200                 if (!*p)
201                         continue;
202
203                 token = match_token(p, tokens, args);
204
205                 terms[i].op = token_to_ruleop[token];
206                 terms[i].operator = token_to_operator[token];
207                 switch (token) {
208
209                 case TOKEN_PATH:
210                 case TOKEN_CMD:
211                 case TOKEN_ARGS:
212                 case TOKEN_TAG:
213                 case TOKEN_IPV4:
214                 case TOKEN_IPV6:
215                         // all these tokens can be specified only once
216                         if (*term_mask & (1 << terms[i].op)) {
217                                 nterms = -EINVAL;
218                                 goto out;
219                         }
220                 /*FALLTHRU*/ case TOKEN_CLASS:
221                 case TOKEN_DEP:
222                 case TOKEN_DEP_ADD:
223                 case TOKEN_DEP_DEL:
224                         terms[i].u.string = args->from;
225                         break;
226
227                 case TOKEN_RUID_EQ:
228                 case TOKEN_RUID_LT:
229                 case TOKEN_RUID_GT:
230                 case TOKEN_RUID_NOT:
231                 case TOKEN_RGID_EQ:
232                 case TOKEN_RGID_LT:
233                 case TOKEN_RGID_GT:
234                 case TOKEN_RGID_NOT:
235                 case TOKEN_EUID_EQ:
236                 case TOKEN_EUID_LT:
237                 case TOKEN_EUID_GT:
238                 case TOKEN_EUID_NOT:
239                 case TOKEN_EGID_EQ:
240                 case TOKEN_EGID_LT:
241                 case TOKEN_EGID_GT:
242                 case TOKEN_EGID_NOT:
243                 case TOKEN_XID_EQ:
244                 case TOKEN_XID_LT:
245                 case TOKEN_XID_GT:
246                 case TOKEN_XID_NOT:
247                         // all these tokens can be specified only once
248                         if (*term_mask & (1 << terms[i].op)) {
249                                 nterms = -EINVAL;
250                                 goto out;
251                         }
252                 /*FALLTHRU*/ case TOKEN_ORDER:
253                 case TOKEN_STATE:
254                         if (match_int(args, &option)) {
255                                 nterms = -EINVAL;
256                                 goto out;
257                         }
258                         terms[i].u.id = option;
259                         break;
260                 default:
261                         nterms = -EINVAL;
262                         goto out;
263                 }
264                 *term_mask |= (1 << terms[i].op);
265                 i++;
266         }
267         *rterms = terms;
268
269       out:
270         if (nterms < 0) {
271                 kfree(terms);
272                 *term_mask = 0;
273         }                       /* else {
274                                    for (i = 0; i < nterms; i++) {
275                                    printk("token: i %d; op %d, operator %d, str %ld\n",
276                                    i, terms[i].op, terms[i].operator, terms[i].u.id);
277                                    }
278                                    } */
279         return nterms;
280 }