Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : 4 : idmap NSS backend 5 : 6 : Copyright (C) Simo Sorce 2006 7 : 8 : This program is free software; you can redistribute it and/or modify 9 : it under the terms of the GNU General Public License as published by 10 : the Free Software Foundation; either version 3 of the License, or 11 : (at your option) any later version. 12 : 13 : This program is distributed in the hope that it will be useful, 14 : but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : GNU General Public License for more details. 17 : 18 : You should have received a copy of the GNU General Public License 19 : along with this program. If not, see <http://www.gnu.org/licenses/>. 20 : */ 21 : 22 : #include "includes.h" 23 : #include "system/passwd.h" 24 : #include "winbindd.h" 25 : #include "nsswitch/winbind_client.h" 26 : #include "idmap.h" 27 : #include "lib/winbind_util.h" 28 : #include "libcli/security/dom_sid.h" 29 : 30 : #undef DBGC_CLASS 31 : #define DBGC_CLASS DBGC_IDMAP 32 : 33 : /***************************** 34 : Initialise idmap database. 35 : *****************************/ 36 : 37 0 : static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom) 38 : { 39 0 : return NT_STATUS_OK; 40 : } 41 : 42 : /********************************** 43 : lookup a set of unix ids. 44 : **********************************/ 45 : 46 0 : static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids) 47 : { 48 0 : int i; 49 : 50 : /* initialize the status to avoid surprise */ 51 0 : for (i = 0; ids[i]; i++) { 52 0 : ids[i]->status = ID_UNKNOWN; 53 : } 54 : 55 0 : for (i = 0; ids[i]; i++) { 56 0 : struct passwd *pw; 57 0 : struct group *gr; 58 0 : const char *name; 59 0 : struct dom_sid sid; 60 0 : enum lsa_SidType type; 61 0 : bool ret; 62 : 63 0 : switch (ids[i]->xid.type) { 64 0 : case ID_TYPE_UID: 65 0 : pw = getpwuid((uid_t)ids[i]->xid.id); 66 : 67 0 : if (!pw) { 68 0 : ids[i]->status = ID_UNMAPPED; 69 0 : continue; 70 : } 71 0 : name = pw->pw_name; 72 0 : break; 73 0 : case ID_TYPE_GID: 74 0 : gr = getgrgid((gid_t)ids[i]->xid.id); 75 : 76 0 : if (!gr) { 77 0 : ids[i]->status = ID_UNMAPPED; 78 0 : continue; 79 : } 80 0 : name = gr->gr_name; 81 0 : break; 82 0 : default: /* ?? */ 83 0 : ids[i]->status = ID_UNKNOWN; 84 0 : continue; 85 : } 86 : 87 : /* by default calls to winbindd are disabled 88 : the following call will not recurse so this is safe */ 89 0 : (void)winbind_on(); 90 : /* Lookup name from PDC using lsa_lookup_names() */ 91 0 : ret = winbind_lookup_name(dom->name, name, &sid, &type); 92 0 : (void)winbind_off(); 93 : 94 0 : if (!ret) { 95 : /* TODO: how do we know if the name is really not mapped, 96 : * or something just failed ? */ 97 0 : ids[i]->status = ID_UNMAPPED; 98 0 : continue; 99 : } 100 : 101 0 : switch (type) { 102 0 : case SID_NAME_USER: 103 0 : if (ids[i]->xid.type == ID_TYPE_UID) { 104 0 : sid_copy(ids[i]->sid, &sid); 105 0 : ids[i]->status = ID_MAPPED; 106 : } 107 0 : break; 108 : 109 0 : case SID_NAME_DOM_GRP: 110 : case SID_NAME_ALIAS: 111 : case SID_NAME_WKN_GRP: 112 0 : if (ids[i]->xid.type == ID_TYPE_GID) { 113 0 : sid_copy(ids[i]->sid, &sid); 114 0 : ids[i]->status = ID_MAPPED; 115 : } 116 0 : break; 117 : 118 0 : default: 119 0 : ids[i]->status = ID_UNKNOWN; 120 0 : break; 121 : } 122 : } 123 0 : return NT_STATUS_OK; 124 : } 125 : 126 : /********************************** 127 : lookup a set of sids. 128 : **********************************/ 129 : 130 0 : static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids) 131 : { 132 0 : int i; 133 : 134 : /* initialize the status to avoid surprise */ 135 0 : for (i = 0; ids[i]; i++) { 136 0 : ids[i]->status = ID_UNKNOWN; 137 : } 138 : 139 0 : for (i = 0; ids[i]; i++) { 140 0 : struct group *gr; 141 0 : enum lsa_SidType type; 142 0 : const char *_domain = NULL; 143 0 : const char *_name = NULL; 144 0 : char *domain = NULL; 145 0 : char *name = NULL; 146 0 : bool ret; 147 : 148 : /* by default calls to winbindd are disabled 149 : the following call will not recurse so this is safe */ 150 0 : (void)winbind_on(); 151 0 : ret = winbind_lookup_sid(talloc_tos(), 152 0 : ids[i]->sid, 153 : &_domain, 154 : &_name, 155 : &type); 156 0 : (void)winbind_off(); 157 0 : if (!ret) { 158 : /* TODO: how do we know if the name is really not mapped, 159 : * or something just failed ? */ 160 0 : ids[i]->status = ID_UNMAPPED; 161 0 : continue; 162 : } 163 : 164 0 : domain = discard_const_p(char, _domain); 165 0 : name = discard_const_p(char, _name); 166 : 167 0 : if (!strequal(domain, dom->name)) { 168 0 : struct dom_sid_buf buf; 169 0 : DBG_ERR("DOMAIN[%s] ignoring SID[%s] belongs to %s [%s\\%s]\n", 170 : dom->name, dom_sid_str_buf(ids[i]->sid, &buf), 171 : sid_type_lookup(type), domain, name); 172 0 : ids[i]->status = ID_UNMAPPED; 173 0 : continue; 174 : } 175 : 176 0 : switch (type) { 177 0 : case SID_NAME_USER: { 178 0 : struct passwd *pw; 179 : 180 : /* this will find also all lower case name and use username level */ 181 : 182 0 : pw = Get_Pwnam_alloc(talloc_tos(), name); 183 0 : if (pw) { 184 0 : ids[i]->xid.id = pw->pw_uid; 185 0 : ids[i]->xid.type = ID_TYPE_UID; 186 0 : ids[i]->status = ID_MAPPED; 187 : } 188 0 : TALLOC_FREE(pw); 189 0 : break; 190 : } 191 : 192 0 : case SID_NAME_DOM_GRP: 193 : case SID_NAME_ALIAS: 194 : case SID_NAME_WKN_GRP: 195 : 196 0 : gr = getgrnam(name); 197 0 : if (gr) { 198 0 : ids[i]->xid.id = gr->gr_gid; 199 0 : ids[i]->xid.type = ID_TYPE_GID; 200 0 : ids[i]->status = ID_MAPPED; 201 : } 202 0 : break; 203 : 204 0 : default: 205 0 : ids[i]->status = ID_UNKNOWN; 206 0 : break; 207 : } 208 0 : TALLOC_FREE(domain); 209 0 : TALLOC_FREE(name); 210 : } 211 0 : return NT_STATUS_OK; 212 : } 213 : 214 : /********************************** 215 : Close the idmap tdb instance 216 : **********************************/ 217 : 218 : static const struct idmap_methods nss_methods = { 219 : .init = idmap_nss_int_init, 220 : .unixids_to_sids = idmap_nss_unixids_to_sids, 221 : .sids_to_unixids = idmap_nss_sids_to_unixids, 222 : }; 223 : 224 0 : NTSTATUS idmap_nss_init(TALLOC_CTX *mem_ctx) 225 : { 226 0 : return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "nss", &nss_methods); 227 : }