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 2 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, write to the Free Software 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21*/ 22 23#include "includes.h" 24#include "winbindd.h" 25 26#undef DBGC_CLASS 27#define DBGC_CLASS DBGC_IDMAP 28 29/***************************** 30 Initialise idmap database. 31*****************************/ 32 33static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom) 34{ 35 dom->initialized = True; 36 return NT_STATUS_OK; 37} 38 39/********************************** 40 lookup a set of unix ids. 41**********************************/ 42 43static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids) 44{ 45 TALLOC_CTX *ctx; 46 int i; 47 48 if (! dom->initialized) { 49 return NT_STATUS_UNSUCCESSFUL; 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 winbind_on(); 92 /* Lookup name from PDC using lsa_lookup_names() */ 93 ret = winbind_lookup_name(dom->name, name, ids[i]->sid, &type); 94 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 if (! dom->initialized) { 139 return NT_STATUS_UNSUCCESSFUL; 140 } 141 142 ctx = talloc_new(dom); 143 if ( ! ctx) { 144 DEBUG(0, ("Out of memory!\n")); 145 return NT_STATUS_NO_MEMORY; 146 } 147 148 for (i = 0; ids[i]; i++) { 149 struct passwd *pw; 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 winbind_on(); 159 ret = winbind_lookup_sid(ctx, ids[i]->sid, &dom_name, &name, &type); 160 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 172 /* this will find also all lower case name and use username level */ 173 174 pw = Get_Pwnam(name); 175 if (pw) { 176 ids[i]->xid.id = pw->pw_uid; 177 ids[i]->xid.type = ID_TYPE_UID; 178 ids[i]->status = ID_MAPPED; 179 } 180 break; 181 182 case SID_NAME_DOM_GRP: 183 case SID_NAME_ALIAS: 184 case SID_NAME_WKN_GRP: 185 186 gr = getgrnam(name); 187 if (gr) { 188 ids[i]->xid.id = gr->gr_gid; 189 ids[i]->xid.type = ID_TYPE_GID; 190 ids[i]->status = ID_MAPPED; 191 } 192 break; 193 194 default: 195 ids[i]->status = ID_UNKNOWN; 196 break; 197 } 198 } 199 200 talloc_free(ctx); 201 return NT_STATUS_OK; 202} 203 204/********************************** 205 Close the idmap tdb instance 206**********************************/ 207 208static NTSTATUS idmap_nss_close(struct idmap_domain *dom) 209{ 210 return NT_STATUS_OK; 211} 212 213static struct idmap_methods nss_methods = { 214 215 .init = idmap_nss_int_init, 216 .unixids_to_sids = idmap_nss_unixids_to_sids, 217 .sids_to_unixids = idmap_nss_sids_to_unixids, 218 .close_fn = idmap_nss_close 219}; 220 221NTSTATUS idmap_nss_init(void) 222{ 223 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "nss", &nss_methods); 224} 225