File: gradm_nest.c

package info (click to toggle)
gradm2 3.1~201709030627-1
  • links: PTS
  • area: main
  • in suites: buster
  • size: 852 kB
  • sloc: ansic: 10,798; lex: 1,248; yacc: 1,212; makefile: 1,178; sh: 15; cs: 9
file content (101 lines) | stat: -rw-r--r-- 3,329 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
 * Copyright (C) 2002-2016 Bradley Spengler, Open Source Security, Inc.
 *        http://www.grsecurity.net spender@grsecurity.net
 *
 * This file is part of gradm.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "gradm.h"

void
add_proc_nested_acl(struct role_acl *role, const char *mainsubjname,
		    const char * const *nestednames, int nestlen, u_int32_t nestmode)
{
	int i;
	char *nestname;
	unsigned int namelen = 0;
	struct proc_acl *stmp;
	struct file_acl *otmp = NULL;
	struct stat fstat;

	if (nestmode & GR_LEARN) {
		fprintf(stderr, "Error on line %lu of %s:\n", lineno,
			current_acl_file);
		fprintf(stderr,
			"Learning is not yet implemented for nested subjects.\n");
		exit(EXIT_FAILURE);
	}

	namelen += strlen(mainsubjname);
	for (i = 0; i < nestlen; i++)
		namelen += strlen(nestednames[i]) + 1;

	nestname = (char *)gr_alloc(namelen + 1);
	strcpy(nestname, mainsubjname);
	for (i = 0; i < nestlen; i++)
		sprintf(nestname + strlen(nestname), ":%s", nestednames[i]);

	stmp = lookup_acl_subject_by_name(role, mainsubjname);
	if (stmp == NULL) {
		fprintf(stderr,
			"No subject %s found for nested subject %s specified on line %lu of %s.\n",
			mainsubjname, nestname, lineno, current_acl_file);
		exit(EXIT_FAILURE);
	}

	for (i = 0; i < nestlen; i++) {
		otmp = lookup_acl_object_by_name(stmp, nestednames[i]);
		if (otmp == NULL) {
			fprintf(stderr,
				"No object %s found for nested subject %s "
				"specified on line %lu of %s.\n",
				nestednames[i], nestname, lineno,
				current_acl_file);
			exit(EXIT_FAILURE);
		} else if (!otmp->nested && (i != nestlen - 1)) {
			fprintf(stderr,
				"No nested subject %s found for nested "
				"subject %s specified on line %lu of %s.\n",
				nestednames[i], nestname, lineno,
				current_acl_file);
			exit(EXIT_FAILURE);
		} else if (otmp->nested && (i == nestlen - 1)) {
			fprintf(stderr,
				"Duplicate nested subject %s found on line "
				"%lu of %s.\n",
				nestname, lineno, current_acl_file);
			exit(EXIT_FAILURE);
		}
		if (i != nestlen - 1)
			stmp = otmp->nested;
	}

	add_proc_subject_acl(role, nestednames[i - 1], nestmode, GR_FFAKE);

	namelen = strlen(nestednames[i-1]);
	for_each_file_object(otmp, stmp) {
		if (!strncmp(nestednames[i-1], otmp->filename, namelen) && (otmp->filename[namelen] == '/' || otmp->filename[namelen] == '\0'))
			if (otmp->mode & GR_EXEC)
				otmp->nested = current_subject;
	}
	if (!(current_subject->mode & GR_OVERRIDE) && strcmp(current_subject->filename, "/"))
		current_subject->parent_subject = stmp;

	if (!stat(nestednames[i - 1], &fstat) && S_ISREG(fstat.st_mode))
		add_proc_object_acl(current_subject, nestednames[i - 1], proc_object_mode_conv("rx"), GR_FLEARN);

	return;
}