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