1
/* $Id: parser_merge.c 505 2007-03-30 15:59:13Z agruen $ */
4
* Copyright (c) 1999, 2000, 2003, 2004, 2005 NOVELL (All rights reserved)
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of version 2 of the GNU General Public
8
* License published by the Free Software Foundation.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, contact Novell, Inc.
19
#include <linux/unistd.h>
26
#define _(s) gettext(s)
31
static inline int count_net_entries(struct codomain *cod)
33
struct cod_net_entry *list;
35
for (list = cod->net_entries; list; list = list->next)
40
static int file_comp(const void *c1, const void *c2)
42
struct cod_entry **e1, **e2;
43
e1 = (struct cod_entry **)c1;
44
e2 = (struct cod_entry **)c2;
45
//PERROR("strcmp %s %s\n", (*e1)->name, (*e2)->name);
46
return strcmp((*e1)->name, (*e2)->name);
49
static int process_file_entries(struct codomain *cod)
52
struct cod_entry *flist, *cur, *next;
53
struct cod_entry **table;
55
for (flist = cod->entries, n = 0; flist; flist = flist->next)
62
table = malloc(sizeof(struct cod_entry *) * (count + 1));
64
PERROR(_("Couldn't merge entries. Out of Memory\n"));
69
for (flist = cod->entries; flist; flist = flist->next) {
74
qsort(table, count, sizeof(struct cod_entry *), file_comp);
77
#define CHECK_CONFLICT_UNSAFE(a, b) \
78
((HAS_EXEC_UNSAFE(a) ^ HAS_EXEC_UNSAFE(b)) && \
79
((HAS_EXEC_PROFILE(a) && HAS_EXEC_PROFILE(b)) || \
80
(HAS_EXEC_UNCONSTRAINED(a) && HAS_EXEC_UNCONSTRAINED(b))))
82
/* walk the sorted table merging similar entries */
83
for (cur = table[0], next = table[1], n = 1; next != NULL; n++, next = table[n]) {
84
if (file_comp(&cur, &next) == 0) {
85
int conflict = CHECK_CONFLICT_UNSAFE(cur->mode, next->mode);
87
cur->mode |= next->mode;
88
/* check for merged x consistency */
89
if (HAS_MAY_EXEC(cur->mode) &&
90
(!AA_EXEC_SINGLE_MODIFIER_SET(cur->mode) ||
92
PERROR(_("profile %s: has merged rule %s with multiple x modifiers\n"),
93
cod->name, cur->name);
104
/* rebuild the file_entry chain */
106
for (n = 1; n < count; n++) {
107
if (table[n] != NULL) {
108
cur->next = table[n];
113
cod->entries = table[0];
120
static int process_net_entries(struct codomain __unused *cod)
125
int codomain_merge_rules(struct codomain *cod)
127
if (!process_file_entries(cod))
129
if (!process_net_entries(cod))
132
/* XXX return error from this */
133
merge_hat_rules(cod);