/* Unix SMB/CIFS implementation. ads (active directory) utility library Copyright (C) Guenther Deschner 2005-2006 Copyright (C) Gerald (Jerry) Carter 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" #ifdef HAVE_LDAP ADS_STATUS ads_get_attrnames_by_oids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *schema_path, const char **OIDs, size_t num_OIDs, char ***OIDs_out, char ***names, size_t *count) { ADS_STATUS status; LDAPMessage *res = NULL; LDAPMessage *msg; char *expr = NULL; const char *attrs[] = { "lDAPDisplayName", "attributeId", NULL }; int i = 0, p = 0; if (!ads || !mem_ctx || !names || !count || !OIDs || !OIDs_out) { return ADS_ERROR(LDAP_PARAM_ERROR); } if (num_OIDs == 0 || OIDs[0] == NULL) { return ADS_ERROR_NT(NT_STATUS_NONE_MAPPED); } if ((expr = talloc_asprintf(mem_ctx, "(|")) == NULL) { return ADS_ERROR(LDAP_NO_MEMORY); } for (i=0; ischema.posix_uidnumber_attr = NULL; ads->schema.posix_gidnumber_attr = NULL; ads->schema.posix_homedir_attr = NULL; ads->schema.posix_shell_attr = NULL; ads->schema.posix_gecos_attr = NULL; ctx = talloc_init("ads_check_posix_schema_mapping"); if (ctx == NULL) { return ADS_ERROR(LDAP_NO_MEMORY); } /* establish a new ldap tcp session if necessary */ if (!ads->ld) { if ((ads_s = ads_init(ads->server.realm, ads->server.workgroup, ads->server.ldap_server)) == NULL) { status = ADS_ERROR(LDAP_SERVER_DOWN); goto done; } ads_s->auth.flags = ADS_AUTH_ANON_BIND; status = ads_connect(ads_s); if (!ADS_ERR_OK(status)) { goto done; } } status = ads_schema_path(ads, ctx, &schema_path); if (!ADS_ERR_OK(status)) { DEBUG(3,("ads_check_posix_mapping: Unable to retrieve schema DN!\n")); goto done; } if (map_type == WB_POSIX_MAP_SFU) { status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_sfu, ARRAY_SIZE(oids_sfu), &oids_out, &names_out, &num_names); } else { status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_rfc2307, ARRAY_SIZE(oids_rfc2307), &oids_out, &names_out, &num_names); } if (!ADS_ERR_OK(status)) { DEBUG(3,("ads_check_posix_schema_mapping: failed %s\n", ads_errstr(status))); goto done; } DEBUG(10,("ads_check_posix_schema_mapping: query succeeded, identified: %s\n", wb_posix_map_str(map_type))); for (i=0; ischema.posix_uidnumber_attr); ads->schema.posix_uidnumber_attr = SMB_STRDUP(names_out[i]); } if (strequal(ADS_ATTR_RFC2307_GIDNUMBER_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_GIDNUMBER_OID, oids_out[i])) { SAFE_FREE(ads->schema.posix_gidnumber_attr); ads->schema.posix_gidnumber_attr = SMB_STRDUP(names_out[i]); } if (strequal(ADS_ATTR_RFC2307_HOMEDIR_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_HOMEDIR_OID, oids_out[i])) { SAFE_FREE(ads->schema.posix_homedir_attr); ads->schema.posix_homedir_attr = SMB_STRDUP(names_out[i]); } if (strequal(ADS_ATTR_RFC2307_SHELL_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_SHELL_OID, oids_out[i])) { SAFE_FREE(ads->schema.posix_shell_attr); ads->schema.posix_shell_attr = SMB_STRDUP(names_out[i]); } if (strequal(ADS_ATTR_RFC2307_GECOS_OID, oids_out[i]) || strequal(ADS_ATTR_SFU_GECOS_OID, oids_out[i])) { SAFE_FREE(ads->schema.posix_gecos_attr); ads->schema.posix_gecos_attr = SMB_STRDUP(names_out[i]); } } if (!ads->schema.posix_uidnumber_attr || !ads->schema.posix_gidnumber_attr || !ads->schema.posix_homedir_attr || !ads->schema.posix_shell_attr || !ads->schema.posix_gecos_attr) { status = ADS_ERROR(LDAP_NO_MEMORY); goto done; } status = ADS_ERROR(LDAP_SUCCESS); ads->schema.map_type = map_type; done: /* free any temporary ads connections */ if (ads_s != ads) { ads_destroy(&ads_s); } if (ctx) { talloc_destroy(ctx); } return status; } #endif