1/*
2   Unix SMB/Netbios implementation.
3   Version 1.9.
4   Security context tests
5   Copyright (C) Tim Potter 2000
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include "includes.h"
22#include "se_access_check_utils.h"
23
24void char_to_sid(DOM_SID *sid, char *sid_str)
25{
26	/* If it looks like a SID, call string_to_sid() else look it up
27	   using wbinfo. */
28
29	if (strncmp(sid_str, "S-", 2) == 0) {
30		string_to_sid(sid, sid_str);
31	} else {
32		struct winbindd_request request;
33		struct winbindd_response response;
34
35		/* Send off request */
36
37		ZERO_STRUCT(request);
38		ZERO_STRUCT(response);
39
40		fstrcpy(request.data.name, sid_str);
41		if (winbindd_request(WINBINDD_LOOKUPNAME, &request,
42				     &response) != NSS_STATUS_SUCCESS) {
43			printf("FAIL: unable to look up sid for name %s\n",
44			       sid_str);
45			exit(1);
46		}
47
48		string_to_sid(sid, response.data.sid.sid);
49		printf("converted char %s to sid %s\n", sid_str,
50		       response.data.sid.sid);
51	}
52}
53
54/* Construct an ACL from a list of ace_entry structures */
55
56SEC_ACL *build_acl(struct ace_entry *ace_list)
57{
58	SEC_ACE *aces = NULL;
59	SEC_ACL *result;
60	int num_aces = 0;
61
62	if (ace_list == NULL) return NULL;
63
64	/* Create aces */
65
66	while(ace_list->sid) {
67		SEC_ACCESS sa;
68		DOM_SID sid;
69
70		/* Create memory for new ACE */
71
72		if (!(aces = Realloc(aces,
73				     sizeof(SEC_ACE) * (num_aces + 1)))) {
74			return NULL;
75		}
76
77		/* Create ace */
78
79		init_sec_access(&sa, ace_list->mask);
80
81		char_to_sid(&sid, ace_list->sid);
82		init_sec_ace(&aces[num_aces], &sid, ace_list->type,
83			     sa, ace_list->flags);
84
85		num_aces++;
86		ace_list++;
87	}
88
89	/* Create ACL from list of ACEs */
90
91	result = make_sec_acl(ACL_REVISION, num_aces, aces);
92	free(aces);
93
94	return result;
95}
96
97/* Make a security descriptor */
98
99SEC_DESC *build_sec_desc(struct ace_entry *dacl, struct ace_entry *sacl,
100			 char *owner_sid, char *group_sid)
101{
102	DOM_SID the_owner_sid, the_group_sid;
103	SEC_ACL *the_dacl, *the_sacl;
104	SEC_DESC *result;
105	size_t size;
106
107	/* Build up bits of security descriptor */
108
109	char_to_sid(&the_owner_sid, owner_sid);
110	char_to_sid(&the_group_sid, group_sid);
111
112	the_dacl = build_acl(dacl);
113	the_sacl = build_acl(sacl);
114
115	result =  make_sec_desc(SEC_DESC_REVISION,
116				SEC_DESC_SELF_RELATIVE | SEC_DESC_DACL_PRESENT,
117				&the_owner_sid, &the_group_sid,
118				the_sacl, the_dacl, &size);
119
120	free_sec_acl(&the_dacl);
121	free_sec_acl(&the_sacl);
122
123	return result;
124}
125
126/* Iterate over password database and call a user-specified function */
127
128void visit_pwdb(BOOL (*fn)(struct passwd *pw, int ngroups, gid_t *groups))
129{
130	struct passwd *pw;
131	int ngroups;
132	gid_t *groups;
133
134	setpwent();
135
136	while ((pw = getpwent())) {
137		BOOL result;
138
139		/* Get grouplist */
140
141		ngroups = getgroups(0, NULL);
142
143		groups = malloc(sizeof(gid_t) * ngroups);
144		getgroups(ngroups, groups);
145
146		/* Call function */
147
148		result = fn(pw, ngroups, groups);
149		if (!result) break;
150
151		/* Clean up */
152
153		free(groups);
154	}
155
156	endpwent();
157}
158