libads/ldap_schema.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    ads (active directory) utility library
00004    Copyright (C) Guenther Deschner 2005-2006
00005    Copyright (C) Gerald (Jerry) Carter 2006
00006    
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011    
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016    
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 */
00021 
00022 #include "includes.h"
00023 
00024 #ifdef HAVE_LDAP
00025 
00026 ADS_STATUS ads_get_attrnames_by_oids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
00027                                      const char *schema_path,
00028                                      const char **OIDs, size_t num_OIDs, 
00029                                      char ***OIDs_out, char ***names, size_t *count)
00030 {
00031         ADS_STATUS status;
00032         LDAPMessage *res = NULL;
00033         LDAPMessage *msg;
00034         char *expr = NULL;
00035         const char *attrs[] = { "lDAPDisplayName", "attributeId", NULL };
00036         int i = 0, p = 0;
00037         
00038         if (!ads || !mem_ctx || !names || !count || !OIDs || !OIDs_out) {
00039                 return ADS_ERROR(LDAP_PARAM_ERROR);
00040         }
00041 
00042         if (num_OIDs == 0 || OIDs[0] == NULL) {
00043                 return ADS_ERROR_NT(NT_STATUS_NONE_MAPPED);
00044         }
00045 
00046         if ((expr = talloc_asprintf(mem_ctx, "(|")) == NULL) {
00047                 return ADS_ERROR(LDAP_NO_MEMORY);
00048         }
00049 
00050         for (i=0; i<num_OIDs; i++) {
00051 
00052                 if ((expr = talloc_asprintf_append(expr, "(attributeId=%s)", 
00053                                                    OIDs[i])) == NULL) {
00054                         return ADS_ERROR(LDAP_NO_MEMORY);
00055                 }
00056         }
00057 
00058         if ((expr = talloc_asprintf_append(expr, ")")) == NULL) {
00059                 return ADS_ERROR(LDAP_NO_MEMORY);
00060         }
00061 
00062         status = ads_do_search_retry(ads, schema_path, 
00063                                      LDAP_SCOPE_SUBTREE, expr, attrs, &res);
00064         if (!ADS_ERR_OK(status)) {
00065                 return status;
00066         }
00067 
00068         *count = ads_count_replies(ads, res);
00069         if (*count == 0 || !res) {
00070                 status = ADS_ERROR_NT(NT_STATUS_NONE_MAPPED);
00071                 goto out;
00072         }
00073 
00074         if (((*names) = TALLOC_ARRAY(mem_ctx, char *, *count)) == NULL) {
00075                 status = ADS_ERROR(LDAP_NO_MEMORY);
00076                 goto out;
00077         }
00078         if (((*OIDs_out) = TALLOC_ARRAY(mem_ctx, char *, *count)) == NULL) {
00079                 status = ADS_ERROR(LDAP_NO_MEMORY);
00080                 goto out;
00081         }
00082 
00083         for (msg = ads_first_entry(ads, res); msg != NULL; 
00084              msg = ads_next_entry(ads, msg)) {
00085 
00086                 (*names)[p]     = ads_pull_string(ads, mem_ctx, msg, 
00087                                                   "lDAPDisplayName");
00088                 (*OIDs_out)[p]  = ads_pull_string(ads, mem_ctx, msg, 
00089                                                   "attributeId");
00090                 if (((*names)[p] == NULL) || ((*OIDs_out)[p] == NULL)) {
00091                         status = ADS_ERROR(LDAP_NO_MEMORY);
00092                         goto out;
00093                 }
00094 
00095                 p++;
00096         }
00097 
00098         if (*count < num_OIDs) {
00099                 status = ADS_ERROR_NT(STATUS_SOME_UNMAPPED);
00100                 goto out;
00101         }
00102 
00103         status = ADS_ERROR(LDAP_SUCCESS);
00104 out:
00105         ads_msgfree(ads, res);
00106 
00107         return status;
00108 }
00109 
00110 const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, const char *schema_path, TALLOC_CTX *mem_ctx, const char * OID)
00111 {
00112         ADS_STATUS rc;
00113         int count = 0;
00114         LDAPMessage *res = NULL;
00115         char *expr = NULL;
00116         const char *attrs[] = { "lDAPDisplayName", NULL };
00117         char *result;
00118 
00119         if (ads == NULL || mem_ctx == NULL || OID == NULL) {
00120                 goto failed;
00121         }
00122 
00123         expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", OID);
00124         if (expr == NULL) {
00125                 goto failed;
00126         }
00127 
00128         rc = ads_do_search_retry(ads, schema_path, LDAP_SCOPE_SUBTREE, 
00129                 expr, attrs, &res);
00130         if (!ADS_ERR_OK(rc)) {
00131                 goto failed;
00132         }
00133 
00134         count = ads_count_replies(ads, res);
00135         if (count == 0 || !res) {
00136                 goto failed;
00137         }
00138 
00139         result = ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName");
00140         ads_msgfree(ads, res);
00141 
00142         return result;
00143         
00144 failed:
00145         DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", 
00146                 OID));
00147         
00148         ads_msgfree(ads, res);
00149         return NULL;
00150 }
00151 
00152 /*********************************************************************
00153 *********************************************************************/
00154 
00155 static ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **schema_path)
00156 {
00157         ADS_STATUS status;
00158         LDAPMessage *res;
00159         const char *schema;
00160         const char *attrs[] = { "schemaNamingContext", NULL };
00161 
00162         status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
00163         if (!ADS_ERR_OK(status)) {
00164                 return status;
00165         }
00166 
00167         if ( (schema = ads_pull_string(ads, mem_ctx, res, "schemaNamingContext")) == NULL ) {
00168                 ads_msgfree(ads, res);
00169                 return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
00170         }
00171 
00172         if ( (*schema_path = talloc_strdup(mem_ctx, schema)) == NULL ) {
00173                 ads_msgfree(ads, res);
00174                 return ADS_ERROR(LDAP_NO_MEMORY);
00175         }
00176 
00177         ads_msgfree(ads, res);
00178 
00179         return status;
00180 }
00181 
00182 /**
00183  * Check for "Services for Unix" or rfc2307 Schema and load some attributes into the ADS_STRUCT
00184  * @param ads connection to ads server
00185  * @param enum mapping type
00186  * @return ADS_STATUS status of search (False if one or more attributes couldn't be
00187  * found in Active Directory)
00188  **/ 
00189 ADS_STATUS ads_check_posix_schema_mapping(TALLOC_CTX *mem_ctx,
00190                                           ADS_STRUCT *ads,
00191                                           enum wb_posix_mapping map_type,
00192                                           struct posix_schema **s ) 
00193 {
00194         TALLOC_CTX *ctx = NULL; 
00195         ADS_STATUS status;
00196         char **oids_out, **names_out;
00197         size_t num_names;
00198         char *schema_path = NULL;
00199         int i;
00200         struct posix_schema *schema = NULL;
00201 
00202         const char *oids_sfu[] = {      ADS_ATTR_SFU_UIDNUMBER_OID,
00203                                         ADS_ATTR_SFU_GIDNUMBER_OID,
00204                                         ADS_ATTR_SFU_HOMEDIR_OID,
00205                                         ADS_ATTR_SFU_SHELL_OID,
00206                                         ADS_ATTR_SFU_GECOS_OID};
00207 
00208         const char *oids_rfc2307[] = {  ADS_ATTR_RFC2307_UIDNUMBER_OID,
00209                                         ADS_ATTR_RFC2307_GIDNUMBER_OID,
00210                                         ADS_ATTR_RFC2307_HOMEDIR_OID,
00211                                         ADS_ATTR_RFC2307_SHELL_OID,
00212                                         ADS_ATTR_RFC2307_GECOS_OID };
00213 
00214         DEBUG(10,("ads_check_posix_schema_mapping\n"));
00215 
00216         if ( (ctx = talloc_init("ads_check_posix_schema_mapping")) == NULL ) {
00217                 return ADS_ERROR(LDAP_NO_MEMORY);
00218         }
00219 
00220         if ( (schema = TALLOC_P(mem_ctx, struct posix_schema)) == NULL ) {
00221                 TALLOC_FREE( ctx );
00222                 return ADS_ERROR(LDAP_NO_MEMORY);
00223         }
00224         
00225         status = ads_schema_path(ads, ctx, &schema_path);
00226         if (!ADS_ERR_OK(status)) {
00227                 DEBUG(3,("ads_check_posix_mapping: Unable to retrieve schema DN!\n"));
00228                 goto done;
00229         }
00230 
00231         if (map_type == WB_POSIX_MAP_SFU) {
00232                 status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_sfu, 
00233                                                    ARRAY_SIZE(oids_sfu), 
00234                                                    &oids_out, &names_out, &num_names);
00235         } else { 
00236                 status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_rfc2307, 
00237                                                    ARRAY_SIZE(oids_rfc2307), 
00238                                                    &oids_out, &names_out, &num_names);
00239         }
00240 
00241         if (!ADS_ERR_OK(status)) {
00242                 DEBUG(3,("ads_check_posix_schema_mapping: failed %s\n", 
00243                         ads_errstr(status)));
00244                 goto done;
00245         }
00246 
00247         for (i=0; i<num_names; i++) {
00248 
00249                 DEBUGADD(10,("\tOID %s has name: %s\n", oids_out[i], names_out[i]));
00250 
00251                 if (strequal(ADS_ATTR_RFC2307_UIDNUMBER_OID, oids_out[i]) ||
00252                     strequal(ADS_ATTR_SFU_UIDNUMBER_OID, oids_out[i])) {
00253                         schema->posix_uidnumber_attr = talloc_strdup(schema, names_out[i]);
00254                         continue;                      
00255                 }
00256 
00257                 if (strequal(ADS_ATTR_RFC2307_GIDNUMBER_OID, oids_out[i]) ||
00258                     strequal(ADS_ATTR_SFU_GIDNUMBER_OID, oids_out[i])) {
00259                         schema->posix_gidnumber_attr = talloc_strdup(schema, names_out[i]);
00260                         continue;               
00261                 }
00262 
00263                 if (strequal(ADS_ATTR_RFC2307_HOMEDIR_OID, oids_out[i]) ||
00264                     strequal(ADS_ATTR_SFU_HOMEDIR_OID, oids_out[i])) {
00265                         schema->posix_homedir_attr = talloc_strdup(schema, names_out[i]);
00266                         continue;                       
00267                 }
00268 
00269                 if (strequal(ADS_ATTR_RFC2307_SHELL_OID, oids_out[i]) ||
00270                     strequal(ADS_ATTR_SFU_SHELL_OID, oids_out[i])) {
00271                         schema->posix_shell_attr = talloc_strdup(schema, names_out[i]);
00272                         continue;                       
00273                 }
00274 
00275                 if (strequal(ADS_ATTR_RFC2307_GECOS_OID, oids_out[i]) ||
00276                     strequal(ADS_ATTR_SFU_GECOS_OID, oids_out[i])) {
00277                         schema->posix_gecos_attr = talloc_strdup(schema, names_out[i]);
00278                 }
00279         }
00280 
00281         if (!schema->posix_uidnumber_attr ||
00282             !schema->posix_gidnumber_attr ||
00283             !schema->posix_homedir_attr ||
00284             !schema->posix_shell_attr ||
00285             !schema->posix_gecos_attr) {
00286                 status = ADS_ERROR(LDAP_NO_MEMORY);
00287                 TALLOC_FREE( schema );          
00288                 goto done;
00289         }
00290 
00291         *s = schema;
00292         
00293         status = ADS_ERROR(LDAP_SUCCESS);
00294         
00295 done:
00296         if (ctx) {
00297                 talloc_destroy(ctx);
00298         }
00299 
00300         return status;
00301 }
00302 
00303 #endif

Sambaに対してSat Aug 29 21:23:01 2009に生成されました。  doxygen 1.4.7