1/* 2 Unix SMB/CIFS implementation. 3 4 Password and authentication handling by wbclient 5 6 Copyright (C) Andrew Bartlett 2002 7 Copyright (C) Jelmer Vernooij 2002 8 Copyright (C) Simo Sorce 2003 9 Copyright (C) Volker Lendecke 2006 10 Copyright (C) Dan Sledz 2009 11 12 This program is free software; you can redistribute it and/or modify 13 it under the terms of the GNU General Public License as published by 14 the Free Software Foundation; either version 3 of the License, or 15 (at your option) any later version. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program. If not, see <http://www.gnu.org/licenses/>. 24*/ 25 26/* This passdb module retrieves full passdb information for local users and 27 * groups from a wbclient compatible daemon. 28 * 29 * The purpose of this module is to defer all SAM authorization information 30 * storage and retrieval to a wbc compatible daemon. 31 * 32 * This passdb backend is most useful when used in conjunction with auth_wbc. 33 * 34 * A few current limitations of this module are: 35 * - read only interface 36 * - no privileges 37 */ 38 39#include "includes.h" 40 41/*************************************************************************** 42 Default implementations of some functions. 43 ****************************************************************************/ 44static NTSTATUS _pdb_wbc_sam_getsampw(struct pdb_methods *methods, 45 struct samu *user, 46 const struct passwd *pwd) 47{ 48 NTSTATUS result = NT_STATUS_OK; 49 50 if (pwd == NULL) 51 return NT_STATUS_NO_SUCH_USER; 52 53 memset(user, 0, sizeof(user)); 54 55 /* Can we really get away with this little of information */ 56 user->methods = methods; 57 result = samu_set_unix(user, pwd); 58 59 return result; 60} 61 62static NTSTATUS pdb_wbc_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname) 63{ 64 return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwnam(sname)); 65} 66 67static NTSTATUS pdb_wbc_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid) 68{ 69 return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwsid(sid)); 70} 71 72static bool pdb_wbc_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid, 73 DOM_SID *sid) 74{ 75 return winbind_uid_to_sid(sid, uid); 76} 77 78static bool pdb_wbc_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid, 79 DOM_SID *sid) 80{ 81 return winbind_gid_to_sid(sid, gid); 82} 83 84static NTSTATUS pdb_wbc_sam_enum_group_members(struct pdb_methods *methods, 85 TALLOC_CTX *mem_ctx, 86 const DOM_SID *group, 87 uint32 **pp_member_rids, 88 size_t *p_num_members) 89{ 90 return NT_STATUS_NOT_IMPLEMENTED; 91} 92 93static NTSTATUS pdb_wbc_sam_enum_group_memberships(struct pdb_methods *methods, 94 TALLOC_CTX *mem_ctx, 95 struct samu *user, 96 DOM_SID **pp_sids, 97 gid_t **pp_gids, 98 size_t *p_num_groups) 99{ 100 size_t i; 101 const char *username = pdb_get_username(user); 102 uint32_t num_groups; 103 104 if (!winbind_get_groups(mem_ctx, username, &num_groups, pp_gids)) { 105 return NT_STATUS_NO_SUCH_USER; 106 } 107 *p_num_groups = num_groups; 108 109 if (*p_num_groups == 0) { 110 smb_panic("primary group missing"); 111 } 112 113 *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups); 114 115 if (*pp_sids == NULL) { 116 TALLOC_FREE(*pp_gids); 117 return NT_STATUS_NO_MEMORY; 118 } 119 120 for (i=0; i < *p_num_groups; i++) { 121 gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]); 122 } 123 124 return NT_STATUS_OK; 125} 126 127static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods, 128 const DOM_SID *domain_sid, 129 int num_rids, 130 uint32 *rids, 131 const char **names, 132 enum lsa_SidType *attrs) 133{ 134 NTSTATUS result = NT_STATUS_OK; 135 char *domain = NULL; 136 char **account_names = NULL; 137 enum lsa_SidType *attr_list = NULL; 138 int i; 139 140 if (!winbind_lookup_rids(talloc_tos(), domain_sid, num_rids, rids, 141 (const char **)&domain, 142 (const char ***)&account_names, &attr_list)) 143 { 144 result = NT_STATUS_NONE_MAPPED; 145 goto done; 146 } 147 148 memcpy(attrs, attr_list, num_rids * sizeof(enum lsa_SidType)); 149 150 for (i=0; i<num_rids; i++) { 151 if (attrs[i] == SID_NAME_UNKNOWN) { 152 names[i] = NULL; 153 } else { 154 names[i] = talloc_strdup(names, account_names[i]); 155 if (names[i] == NULL) { 156 result = NT_STATUS_NO_MEMORY; 157 goto done; 158 } 159 160 } 161 } 162 163done: 164 TALLOC_FREE(account_names); 165 TALLOC_FREE(domain); 166 TALLOC_FREE(attr_list); 167 return result; 168} 169 170static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value) 171{ 172 return NT_STATUS_UNSUCCESSFUL; 173} 174 175static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value) 176{ 177 return NT_STATUS_UNSUCCESSFUL; 178} 179 180static bool pdb_wbc_sam_search_groups(struct pdb_methods *methods, 181 struct pdb_search *search) 182{ 183 return false; 184} 185 186static bool pdb_wbc_sam_search_aliases(struct pdb_methods *methods, 187 struct pdb_search *search, 188 const DOM_SID *sid) 189{ 190 191 return false; 192} 193 194static bool pdb_wbc_sam_get_trusteddom_pw(struct pdb_methods *methods, 195 const char *domain, 196 char **pwd, 197 DOM_SID *sid, 198 time_t *pass_last_set_time) 199{ 200 return false; 201 202} 203 204static bool pdb_wbc_sam_set_trusteddom_pw(struct pdb_methods *methods, 205 const char *domain, 206 const char *pwd, 207 const DOM_SID *sid) 208{ 209 return false; 210} 211 212static bool pdb_wbc_sam_del_trusteddom_pw(struct pdb_methods *methods, 213 const char *domain) 214{ 215 return false; 216} 217 218static NTSTATUS pdb_wbc_sam_enum_trusteddoms(struct pdb_methods *methods, 219 TALLOC_CTX *mem_ctx, 220 uint32 *num_domains, 221 struct trustdom_info ***domains) 222{ 223 return NT_STATUS_NOT_IMPLEMENTED; 224} 225 226static bool _make_group_map(struct pdb_methods *methods, const char *domain, const char *name, enum lsa_SidType name_type, gid_t gid, DOM_SID *sid, GROUP_MAP *map) 227{ 228 snprintf(map->nt_name, sizeof(map->nt_name), "%s%c%s", 229 domain, *lp_winbind_separator(), name); 230 map->sid_name_use = name_type; 231 map->sid = *sid; 232 map->gid = gid; 233 return true; 234} 235 236static NTSTATUS pdb_wbc_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, 237 DOM_SID sid) 238{ 239 NTSTATUS result = NT_STATUS_OK; 240 char *name = NULL; 241 char *domain = NULL; 242 enum lsa_SidType name_type; 243 gid_t gid; 244 245 if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, 246 (const char **) &name, &name_type)) { 247 result = NT_STATUS_NO_SUCH_GROUP; 248 goto done; 249 } 250 251 if ((name_type != SID_NAME_DOM_GRP) && 252 (name_type != SID_NAME_DOMAIN) && 253 (name_type != SID_NAME_ALIAS) && 254 (name_type != SID_NAME_WKN_GRP)) { 255 result = NT_STATUS_NO_SUCH_GROUP; 256 goto done; 257 } 258 259 if (!winbind_sid_to_gid(&gid, &sid)) { 260 result = NT_STATUS_NO_SUCH_GROUP; 261 goto done; 262 } 263 264 if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { 265 result = NT_STATUS_NO_SUCH_GROUP; 266 goto done; 267 } 268 269done: 270 TALLOC_FREE(name); 271 TALLOC_FREE(domain); 272 return result; 273} 274 275static NTSTATUS pdb_wbc_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, 276 gid_t gid) 277{ 278 NTSTATUS result = NT_STATUS_OK; 279 char *name = NULL; 280 char *domain = NULL; 281 DOM_SID sid; 282 enum lsa_SidType name_type; 283 284 if (!winbind_gid_to_sid(&sid, gid)) { 285 result = NT_STATUS_NO_SUCH_GROUP; 286 goto done; 287 } 288 289 if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, 290 (const char **)&name, &name_type)) { 291 result = NT_STATUS_NO_SUCH_GROUP; 292 goto done; 293 } 294 295 if ((name_type != SID_NAME_DOM_GRP) && 296 (name_type != SID_NAME_DOMAIN) && 297 (name_type != SID_NAME_ALIAS) && 298 (name_type != SID_NAME_WKN_GRP)) { 299 result = NT_STATUS_NO_SUCH_GROUP; 300 goto done; 301 } 302 303 if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { 304 result = NT_STATUS_NO_SUCH_GROUP; 305 goto done; 306 } 307 308done: 309 TALLOC_FREE(name); 310 TALLOC_FREE(domain); 311 312 return result; 313} 314 315static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, 316 const char *name) 317{ 318 NTSTATUS result = NT_STATUS_OK; 319 const char *domain = ""; 320 DOM_SID sid; 321 gid_t gid; 322 enum lsa_SidType name_type; 323 324 if (!winbind_lookup_name(domain, name, &sid, &name_type)) { 325 result = NT_STATUS_NO_SUCH_GROUP; 326 goto done; 327 } 328 329 if ((name_type != SID_NAME_DOM_GRP) && 330 (name_type != SID_NAME_DOMAIN) && 331 (name_type != SID_NAME_ALIAS) && 332 (name_type != SID_NAME_WKN_GRP)) { 333 result = NT_STATUS_NO_SUCH_GROUP; 334 goto done; 335 } 336 337 if (!winbind_sid_to_gid(&gid, &sid)) { 338 result = NT_STATUS_NO_SUCH_GROUP; 339 goto done; 340 } 341 342 if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { 343 result = NT_STATUS_NO_SUCH_GROUP; 344 goto done; 345 } 346 347done: 348 349 return result; 350} 351 352static NTSTATUS pdb_wbc_sam_enum_group_mapping(struct pdb_methods *methods, 353 const DOM_SID *sid, enum lsa_SidType sid_name_use, 354 GROUP_MAP **pp_rmap, size_t *p_num_entries, 355 bool unix_only) 356{ 357 return NT_STATUS_NOT_IMPLEMENTED; 358} 359 360static NTSTATUS pdb_wbc_sam_get_aliasinfo(struct pdb_methods *methods, 361 const DOM_SID *sid, 362 struct acct_info *info) 363{ 364 return NT_STATUS_NOT_IMPLEMENTED; 365} 366 367static NTSTATUS pdb_wbc_sam_enum_aliasmem(struct pdb_methods *methods, 368 const DOM_SID *alias, 369 TALLOC_CTX *mem_ctx, 370 DOM_SID **pp_members, 371 size_t *p_num_members) 372{ 373 return NT_STATUS_NOT_IMPLEMENTED; 374} 375 376static NTSTATUS pdb_wbc_sam_alias_memberships(struct pdb_methods *methods, 377 TALLOC_CTX *mem_ctx, 378 const DOM_SID *domain_sid, 379 const DOM_SID *members, 380 size_t num_members, 381 uint32 **pp_alias_rids, 382 size_t *p_num_alias_rids) 383{ 384 if (!winbind_get_sid_aliases(mem_ctx, domain_sid, 385 members, num_members, pp_alias_rids, p_num_alias_rids)) 386 return NT_STATUS_UNSUCCESSFUL; 387 388 return NT_STATUS_OK; 389} 390 391static NTSTATUS pdb_init_wbc_sam(struct pdb_methods **pdb_method, const char *location) 392{ 393 NTSTATUS result; 394 395 if (!NT_STATUS_IS_OK(result = make_pdb_method( pdb_method))) { 396 return result; 397 } 398 399 (*pdb_method)->name = "wbc_sam"; 400 401 (*pdb_method)->getsampwnam = pdb_wbc_sam_getsampwnam; 402 (*pdb_method)->getsampwsid = pdb_wbc_sam_getsampwsid; 403 404 (*pdb_method)->getgrsid = pdb_wbc_sam_getgrsid; 405 (*pdb_method)->getgrgid = pdb_wbc_sam_getgrgid; 406 (*pdb_method)->getgrnam = pdb_wbc_sam_getgrnam; 407 (*pdb_method)->enum_group_mapping = pdb_wbc_sam_enum_group_mapping; 408 (*pdb_method)->enum_group_members = pdb_wbc_sam_enum_group_members; 409 (*pdb_method)->enum_group_memberships = pdb_wbc_sam_enum_group_memberships; 410 (*pdb_method)->get_aliasinfo = pdb_wbc_sam_get_aliasinfo; 411 (*pdb_method)->enum_aliasmem = pdb_wbc_sam_enum_aliasmem; 412 (*pdb_method)->enum_alias_memberships = pdb_wbc_sam_alias_memberships; 413 (*pdb_method)->lookup_rids = pdb_wbc_sam_lookup_rids; 414 (*pdb_method)->get_account_policy = pdb_wbc_sam_get_account_policy; 415 (*pdb_method)->set_account_policy = pdb_wbc_sam_set_account_policy; 416 (*pdb_method)->uid_to_sid = pdb_wbc_sam_uid_to_sid; 417 (*pdb_method)->gid_to_sid = pdb_wbc_sam_gid_to_sid; 418 419 (*pdb_method)->search_groups = pdb_wbc_sam_search_groups; 420 (*pdb_method)->search_aliases = pdb_wbc_sam_search_aliases; 421 422 (*pdb_method)->get_trusteddom_pw = pdb_wbc_sam_get_trusteddom_pw; 423 (*pdb_method)->set_trusteddom_pw = pdb_wbc_sam_set_trusteddom_pw; 424 (*pdb_method)->del_trusteddom_pw = pdb_wbc_sam_del_trusteddom_pw; 425 (*pdb_method)->enum_trusteddoms = pdb_wbc_sam_enum_trusteddoms; 426 427 (*pdb_method)->private_data = NULL; 428 (*pdb_method)->free_private_data = NULL; 429 430 return NT_STATUS_OK; 431} 432 433NTSTATUS pdb_wbc_sam_init(void) 434{ 435 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "wbc_sam", pdb_init_wbc_sam); 436} 437