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 2 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, write to the Free Software
19   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include "includes.h"
23#include "se_access_check_utils.h"
24
25void char_to_sid(DOM_SID *sid, char *sid_str)
26{
27	/* If it looks like a SID, call string_to_sid() else look it up
28	   using wbinfo. */
29
30	if (strncmp(sid_str, "S-", 2) == 0) {
31		string_to_sid(sid, sid_str);
32	} else {
33		struct winbindd_request request;
34		struct winbindd_response response;
35
36		/* Send off request */
37
38		ZERO_STRUCT(request);
39		ZERO_STRUCT(response);
40
41		fstrcpy(request.data.name, sid_str);
42		if (winbindd_request(WINBINDD_LOOKUPNAME, &request,
43				     &response) != NSS_STATUS_SUCCESS) {
44			printf("FAIL: unable to look up sid for name %s\n",
45			       sid_str);
46			exit(1);
47		}
48
49		string_to_sid(sid, response.data.sid.sid);
50		printf("converted char %s to sid %s\n", sid_str,
51		       response.data.sid.sid);
52	}
53}
54
55/* Construct an ACL from a list of ace_entry structures */
56
57SEC_ACL *build_acl(struct ace_entry *ace_list)
58{
59	SEC_ACE *aces = NULL;
60	SEC_ACL *result;
61	int num_aces = 0;
62
63	if (ace_list == NULL) return NULL;
64
65	/* Create aces */
66
67	while(ace_list->sid) {
68		SEC_ACCESS sa;
69		DOM_SID sid;
70
71		/* Create memory for new ACE */
72
73		if (!(aces = Realloc(aces,
74				     sizeof(SEC_ACE) * (num_aces + 1)))) {
75			return NULL;
76		}
77
78		/* Create ace */
79
80		init_sec_access(&sa, ace_list->mask);
81
82		char_to_sid(&sid, ace_list->sid);
83		init_sec_ace(&aces[num_aces], &sid, ace_list->type,
84			     sa, ace_list->flags);
85
86		num_aces++;
87		ace_list++;
88	}
89
90	/* Create ACL from list of ACEs */
91
92	result = make_sec_acl(ACL_REVISION, num_aces, aces);
93	free(aces);
94
95	return result;
96}
97
98/* Make a security descriptor */
99
100SEC_DESC *build_sec_desc(struct ace_entry *dacl, struct ace_entry *sacl,
101			 char *owner_sid, char *group_sid)
102{
103	DOM_SID the_owner_sid, the_group_sid;
104	SEC_ACL *the_dacl, *the_sacl;
105	SEC_DESC *result;
106	size_t size;
107
108	/* Build up bits of security descriptor */
109
110	char_to_sid(&the_owner_sid, owner_sid);
111	char_to_sid(&the_group_sid, group_sid);
112
113	the_dacl = build_acl(dacl);
114	the_sacl = build_acl(sacl);
115
116	result =  make_sec_desc(SEC_DESC_REVISION,
117				SEC_DESC_SELF_RELATIVE | SEC_DESC_DACL_PRESENT,
118				&the_owner_sid, &the_group_sid,
119				the_sacl, the_dacl, &size);
120
121	free_sec_acl(&the_dacl);
122	free_sec_acl(&the_sacl);
123
124	return result;
125}
126
127/* Iterate over password database and call a user-specified function */
128
129void visit_pwdb(BOOL (*fn)(struct passwd *pw, int ngroups, gid_t *groups))
130{
131	struct passwd *pw;
132	int ngroups;
133	gid_t *groups;
134
135	setpwent();
136
137	while ((pw = getpwent())) {
138		BOOL result;
139
140		/* Get grouplist */
141
142		ngroups = getgroups(0, NULL);
143
144		groups = malloc(sizeof(gid_t) * ngroups);
145		getgroups(ngroups, groups);
146
147		/* Call function */
148
149		result = fn(pw, ngroups, groups);
150		if (!result) break;
151
152		/* Clean up */
153
154		free(groups);
155	}
156
157	endpwent();
158}
159