se_access_check() tests.
[samba.git] / testsuite / smbd / se_access_check_utils.c
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
25 void 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
57 SEC_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
100 SEC_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
129 void 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 }