1/* 2 Unix SMB/CIFS implementation. 3 4 idmap PASSDB 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 "winbindd.h" 24 25#undef DBGC_CLASS 26#define DBGC_CLASS DBGC_IDMAP 27 28/***************************** 29 Initialise idmap database. 30*****************************/ 31 32static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom, 33 const char *params) 34{ 35 return NT_STATUS_OK; 36} 37 38/********************************** 39 lookup a set of unix ids. 40**********************************/ 41 42static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids) 43{ 44 TALLOC_CTX *ctx; 45 int i; 46 47 /* initialize the status to avoid suprise */ 48 for (i = 0; ids[i]; i++) { 49 ids[i]->status = ID_UNKNOWN; 50 } 51 52 ctx = talloc_new(dom); 53 if ( ! ctx) { 54 DEBUG(0, ("Out of memory!\n")); 55 return NT_STATUS_NO_MEMORY; 56 } 57 58 for (i = 0; ids[i]; i++) { 59 struct passwd *pw; 60 struct group *gr; 61 const char *name; 62 enum lsa_SidType type; 63 bool ret; 64 65 switch (ids[i]->xid.type) { 66 case ID_TYPE_UID: 67 pw = getpwuid((uid_t)ids[i]->xid.id); 68 69 if (!pw) { 70 ids[i]->status = ID_UNMAPPED; 71 continue; 72 } 73 name = pw->pw_name; 74 break; 75 case ID_TYPE_GID: 76 gr = getgrgid((gid_t)ids[i]->xid.id); 77 78 if (!gr) { 79 ids[i]->status = ID_UNMAPPED; 80 continue; 81 } 82 name = gr->gr_name; 83 break; 84 default: /* ?? */ 85 ids[i]->status = ID_UNKNOWN; 86 continue; 87 } 88 89 /* by default calls to winbindd are disabled 90 the following call will not recurse so this is safe */ 91 (void)winbind_on(); 92 /* Lookup name from PDC using lsa_lookup_names() */ 93 ret = winbind_lookup_name(dom->name, name, ids[i]->sid, &type); 94 (void)winbind_off(); 95 96 if (!ret) { 97 /* TODO: how do we know if the name is really not mapped, 98 * or something just failed ? */ 99 ids[i]->status = ID_UNMAPPED; 100 continue; 101 } 102 103 switch (type) { 104 case SID_NAME_USER: 105 if (ids[i]->xid.type == ID_TYPE_UID) { 106 ids[i]->status = ID_MAPPED; 107 } 108 break; 109 110 case SID_NAME_DOM_GRP: 111 case SID_NAME_ALIAS: 112 case SID_NAME_WKN_GRP: 113 if (ids[i]->xid.type == ID_TYPE_GID) { 114 ids[i]->status = ID_MAPPED; 115 } 116 break; 117 118 default: 119 ids[i]->status = ID_UNKNOWN; 120 break; 121 } 122 } 123 124 125 talloc_free(ctx); 126 return NT_STATUS_OK; 127} 128 129/********************************** 130 lookup a set of sids. 131**********************************/ 132 133static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids) 134{ 135 TALLOC_CTX *ctx; 136 int i; 137 138 /* initialize the status to avoid suprise */ 139 for (i = 0; ids[i]; i++) { 140 ids[i]->status = ID_UNKNOWN; 141 } 142 143 ctx = talloc_new(dom); 144 if ( ! ctx) { 145 DEBUG(0, ("Out of memory!\n")); 146 return NT_STATUS_NO_MEMORY; 147 } 148 149 for (i = 0; ids[i]; i++) { 150 struct group *gr; 151 enum lsa_SidType type; 152 const char *dom_name = NULL; 153 const char *name = NULL; 154 bool ret; 155 156 /* by default calls to winbindd are disabled 157 the following call will not recurse so this is safe */ 158 (void)winbind_on(); 159 ret = winbind_lookup_sid(ctx, ids[i]->sid, &dom_name, &name, &type); 160 (void)winbind_off(); 161 162 if (!ret) { 163 /* TODO: how do we know if the name is really not mapped, 164 * or something just failed ? */ 165 ids[i]->status = ID_UNMAPPED; 166 continue; 167 } 168 169 switch (type) { 170 case SID_NAME_USER: { 171 struct passwd *pw; 172 173 /* this will find also all lower case name and use username level */ 174 175 pw = Get_Pwnam_alloc(talloc_tos(), name); 176 if (pw) { 177 ids[i]->xid.id = pw->pw_uid; 178 ids[i]->xid.type = ID_TYPE_UID; 179 ids[i]->status = ID_MAPPED; 180 } 181 TALLOC_FREE(pw); 182 break; 183 } 184 185 case SID_NAME_DOM_GRP: 186 case SID_NAME_ALIAS: 187 case SID_NAME_WKN_GRP: 188 189 gr = getgrnam(name); 190 if (gr) { 191 ids[i]->xid.id = gr->gr_gid; 192 ids[i]->xid.type = ID_TYPE_GID; 193 ids[i]->status = ID_MAPPED; 194 } 195 break; 196 197 default: 198 ids[i]->status = ID_UNKNOWN; 199 break; 200 } 201 } 202 203 talloc_free(ctx); 204 return NT_STATUS_OK; 205} 206 207/********************************** 208 Close the idmap tdb instance 209**********************************/ 210 211static NTSTATUS idmap_nss_close(struct idmap_domain *dom) 212{ 213 return NT_STATUS_OK; 214} 215 216static struct idmap_methods nss_methods = { 217 218 .init = idmap_nss_int_init, 219 .unixids_to_sids = idmap_nss_unixids_to_sids, 220 .sids_to_unixids = idmap_nss_sids_to_unixids, 221 .close_fn = idmap_nss_close 222}; 223 224NTSTATUS idmap_nss_init(void) 225{ 226 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "nss", &nss_methods); 227} 228