root/source3/libads/ldap_schema.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ads_get_attrnames_by_oids
  2. ads_get_attrname_by_guid
  3. ads_get_attrname_by_oid
  4. ads_schema_path
  5. ads_check_posix_schema_mapping

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    ads (active directory) utility library
   4    Copyright (C) Guenther Deschner 2005-2007
   5    Copyright (C) Gerald (Jerry) Carter 2006
   6    
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 3 of the License, or
  10    (at your option) any later version.
  11    
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16    
  17    You should have received a copy of the GNU General Public License
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19 */
  20 
  21 #include "includes.h"
  22 
  23 #ifdef HAVE_LDAP
  24 
  25 ADS_STATUS ads_get_attrnames_by_oids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  26                                      const char *schema_path,
  27                                      const char **OIDs, size_t num_OIDs, 
  28                                      char ***OIDs_out, char ***names, size_t *count)
  29 {
  30         ADS_STATUS status;
  31         LDAPMessage *res = NULL;
  32         LDAPMessage *msg;
  33         char *expr = NULL;
  34         const char *attrs[] = { "lDAPDisplayName", "attributeId", NULL };
  35         int i = 0, p = 0;
  36         
  37         if (!ads || !mem_ctx || !names || !count || !OIDs || !OIDs_out) {
  38                 return ADS_ERROR(LDAP_PARAM_ERROR);
  39         }
  40 
  41         if (num_OIDs == 0 || OIDs[0] == NULL) {
  42                 return ADS_ERROR_NT(NT_STATUS_NONE_MAPPED);
  43         }
  44 
  45         if ((expr = talloc_asprintf(mem_ctx, "(|")) == NULL) {
  46                 return ADS_ERROR(LDAP_NO_MEMORY);
  47         }
  48 
  49         for (i=0; i<num_OIDs; i++) {
  50 
  51                 if ((expr = talloc_asprintf_append_buffer(expr, "(attributeId=%s)", 
  52                                                    OIDs[i])) == NULL) {
  53                         return ADS_ERROR(LDAP_NO_MEMORY);
  54                 }
  55         }
  56 
  57         if ((expr = talloc_asprintf_append_buffer(expr, ")")) == NULL) {
  58                 return ADS_ERROR(LDAP_NO_MEMORY);
  59         }
  60 
  61         status = ads_do_search_retry(ads, schema_path, 
  62                                      LDAP_SCOPE_SUBTREE, expr, attrs, &res);
  63         if (!ADS_ERR_OK(status)) {
  64                 return status;
  65         }
  66 
  67         *count = ads_count_replies(ads, res);
  68         if (*count == 0 || !res) {
  69                 status = ADS_ERROR_NT(NT_STATUS_NONE_MAPPED);
  70                 goto out;
  71         }
  72 
  73         if (((*names) = TALLOC_ARRAY(mem_ctx, char *, *count)) == NULL) {
  74                 status = ADS_ERROR(LDAP_NO_MEMORY);
  75                 goto out;
  76         }
  77         if (((*OIDs_out) = TALLOC_ARRAY(mem_ctx, char *, *count)) == NULL) {
  78                 status = ADS_ERROR(LDAP_NO_MEMORY);
  79                 goto out;
  80         }
  81 
  82         for (msg = ads_first_entry(ads, res); msg != NULL; 
  83              msg = ads_next_entry(ads, msg)) {
  84 
  85                 (*names)[p]     = ads_pull_string(ads, mem_ctx, msg, 
  86                                                   "lDAPDisplayName");
  87                 (*OIDs_out)[p]  = ads_pull_string(ads, mem_ctx, msg, 
  88                                                   "attributeId");
  89                 if (((*names)[p] == NULL) || ((*OIDs_out)[p] == NULL)) {
  90                         status = ADS_ERROR(LDAP_NO_MEMORY);
  91                         goto out;
  92                 }
  93 
  94                 p++;
  95         }
  96 
  97         if (*count < num_OIDs) {
  98                 status = ADS_ERROR_NT(STATUS_SOME_UNMAPPED);
  99                 goto out;
 100         }
 101 
 102         status = ADS_ERROR(LDAP_SUCCESS);
 103 out:
 104         ads_msgfree(ads, res);
 105 
 106         return status;
 107 }
 108 
 109 const char *ads_get_attrname_by_guid(ADS_STRUCT *ads, 
     /* [<][>][^][v][top][bottom][index][help] */
 110                                      const char *schema_path, 
 111                                      TALLOC_CTX *mem_ctx, 
 112                                      const struct GUID *schema_guid)
 113 {
 114         ADS_STATUS rc;
 115         LDAPMessage *res = NULL;
 116         char *expr = NULL;
 117         const char *attrs[] = { "lDAPDisplayName", NULL };
 118         const char *result = NULL;
 119         char *guid_bin = NULL;
 120 
 121         if (!ads || !mem_ctx || !schema_guid) {
 122                 goto done;
 123         }
 124 
 125         guid_bin = guid_binstring(schema_guid);
 126         if (!guid_bin) {
 127                 goto done;
 128         }
 129 
 130         expr = talloc_asprintf(mem_ctx, "(schemaIDGUID=%s)", guid_bin);
 131         if (!expr) {
 132                 goto done;
 133         }
 134 
 135         rc = ads_do_search_retry(ads, schema_path, LDAP_SCOPE_SUBTREE, 
 136                                  expr, attrs, &res);
 137         if (!ADS_ERR_OK(rc)) {
 138                 goto done;
 139         }
 140 
 141         if (ads_count_replies(ads, res) != 1) {
 142                 goto done;
 143         }
 144 
 145         result = ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName");
 146 
 147  done:
 148         SAFE_FREE(guid_bin);
 149         ads_msgfree(ads, res);
 150         return result;
 151         
 152 }
 153 
 154 const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, const char *schema_path, TALLOC_CTX *mem_ctx, const char * OID)
     /* [<][>][^][v][top][bottom][index][help] */
 155 {
 156         ADS_STATUS rc;
 157         int count = 0;
 158         LDAPMessage *res = NULL;
 159         char *expr = NULL;
 160         const char *attrs[] = { "lDAPDisplayName", NULL };
 161         char *result;
 162 
 163         if (ads == NULL || mem_ctx == NULL || OID == NULL) {
 164                 goto failed;
 165         }
 166 
 167         expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", OID);
 168         if (expr == NULL) {
 169                 goto failed;
 170         }
 171 
 172         rc = ads_do_search_retry(ads, schema_path, LDAP_SCOPE_SUBTREE, 
 173                 expr, attrs, &res);
 174         if (!ADS_ERR_OK(rc)) {
 175                 goto failed;
 176         }
 177 
 178         count = ads_count_replies(ads, res);
 179         if (count == 0 || !res) {
 180                 goto failed;
 181         }
 182 
 183         result = ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName");
 184         ads_msgfree(ads, res);
 185 
 186         return result;
 187         
 188 failed:
 189         DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", 
 190                 OID));
 191         
 192         ads_msgfree(ads, res);
 193         return NULL;
 194 }
 195 /*********************************************************************
 196 *********************************************************************/
 197 
 198 ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **schema_path)
     /* [<][>][^][v][top][bottom][index][help] */
 199 {
 200         ADS_STATUS status;
 201         LDAPMessage *res;
 202         const char *schema;
 203         const char *attrs[] = { "schemaNamingContext", NULL };
 204 
 205         status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
 206         if (!ADS_ERR_OK(status)) {
 207                 return status;
 208         }
 209 
 210         if ( (schema = ads_pull_string(ads, mem_ctx, res, "schemaNamingContext")) == NULL ) {
 211                 ads_msgfree(ads, res);
 212                 return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
 213         }
 214 
 215         if ( (*schema_path = talloc_strdup(mem_ctx, schema)) == NULL ) {
 216                 ads_msgfree(ads, res);
 217                 return ADS_ERROR(LDAP_NO_MEMORY);
 218         }
 219 
 220         ads_msgfree(ads, res);
 221 
 222         return status;
 223 }
 224 
 225 /**
 226  * Check for "Services for Unix" or rfc2307 Schema and load some attributes into the ADS_STRUCT
 227  * @param ads connection to ads server
 228  * @param enum mapping type
 229  * @return ADS_STATUS status of search (False if one or more attributes couldn't be
 230  * found in Active Directory)
 231  **/ 
 232 ADS_STATUS ads_check_posix_schema_mapping(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 233                                           ADS_STRUCT *ads,
 234                                           enum wb_posix_mapping map_type,
 235                                           struct posix_schema **s ) 
 236 {
 237         TALLOC_CTX *ctx = NULL; 
 238         ADS_STATUS status;
 239         char **oids_out, **names_out;
 240         size_t num_names;
 241         char *schema_path = NULL;
 242         int i;
 243         struct posix_schema *schema = NULL;
 244 
 245         const char *oids_sfu[] = {      ADS_ATTR_SFU_UIDNUMBER_OID,
 246                                         ADS_ATTR_SFU_GIDNUMBER_OID,
 247                                         ADS_ATTR_SFU_HOMEDIR_OID,
 248                                         ADS_ATTR_SFU_SHELL_OID,
 249                                         ADS_ATTR_SFU_GECOS_OID,
 250                                         ADS_ATTR_SFU_UID_OID };
 251 
 252         const char *oids_sfu20[] = {    ADS_ATTR_SFU20_UIDNUMBER_OID,
 253                                         ADS_ATTR_SFU20_GIDNUMBER_OID,
 254                                         ADS_ATTR_SFU20_HOMEDIR_OID,
 255                                         ADS_ATTR_SFU20_SHELL_OID,
 256                                         ADS_ATTR_SFU20_GECOS_OID,
 257                                         ADS_ATTR_SFU20_UID_OID };
 258 
 259         const char *oids_rfc2307[] = {  ADS_ATTR_RFC2307_UIDNUMBER_OID,
 260                                         ADS_ATTR_RFC2307_GIDNUMBER_OID,
 261                                         ADS_ATTR_RFC2307_HOMEDIR_OID,
 262                                         ADS_ATTR_RFC2307_SHELL_OID,
 263                                         ADS_ATTR_RFC2307_GECOS_OID,
 264                                         ADS_ATTR_RFC2307_UID_OID };
 265 
 266         DEBUG(10,("ads_check_posix_schema_mapping for schema mode: %d\n", map_type));
 267 
 268         switch (map_type) {
 269         
 270                 case WB_POSIX_MAP_TEMPLATE:
 271                 case WB_POSIX_MAP_UNIXINFO:
 272                         DEBUG(10,("ads_check_posix_schema_mapping: nothing to do\n"));
 273                         return ADS_ERROR(LDAP_SUCCESS);
 274 
 275                 case WB_POSIX_MAP_SFU:
 276                 case WB_POSIX_MAP_SFU20:
 277                 case WB_POSIX_MAP_RFC2307:
 278                         break;
 279 
 280                 default:
 281                         DEBUG(0,("ads_check_posix_schema_mapping: "
 282                                  "unknown enum %d\n", map_type));
 283                         return ADS_ERROR(LDAP_PARAM_ERROR);
 284         }
 285 
 286         if ( (ctx = talloc_init("ads_check_posix_schema_mapping")) == NULL ) {
 287                 return ADS_ERROR(LDAP_NO_MEMORY);
 288         }
 289 
 290         if ( (schema = TALLOC_P(mem_ctx, struct posix_schema)) == NULL ) {
 291                 TALLOC_FREE( ctx );
 292                 return ADS_ERROR(LDAP_NO_MEMORY);
 293         }
 294         
 295         status = ads_schema_path(ads, ctx, &schema_path);
 296         if (!ADS_ERR_OK(status)) {
 297                 DEBUG(3,("ads_check_posix_mapping: Unable to retrieve schema DN!\n"));
 298                 goto done;
 299         }
 300 
 301         switch (map_type) {
 302                 case WB_POSIX_MAP_SFU:
 303                         status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_sfu, 
 304                                                            ARRAY_SIZE(oids_sfu), 
 305                                                            &oids_out, &names_out, &num_names);
 306                         break;
 307                 case WB_POSIX_MAP_SFU20:
 308                         status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_sfu20, 
 309                                                            ARRAY_SIZE(oids_sfu20), 
 310                                                            &oids_out, &names_out, &num_names);
 311                         break;
 312                 case WB_POSIX_MAP_RFC2307:
 313                         status = ads_get_attrnames_by_oids(ads, ctx, schema_path, oids_rfc2307, 
 314                                                            ARRAY_SIZE(oids_rfc2307), 
 315                                                            &oids_out, &names_out, &num_names);
 316                         break;
 317                 default:
 318                         status = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 319                         break;
 320         }
 321 
 322         if (!ADS_ERR_OK(status)) {
 323                 DEBUG(3,("ads_check_posix_schema_mapping: failed %s\n", 
 324                         ads_errstr(status)));
 325                 goto done;
 326         }
 327 
 328         for (i=0; i<num_names; i++) {
 329 
 330                 DEBUGADD(10,("\tOID %s has name: %s\n", oids_out[i], names_out[i]));
 331 
 332                 if (strequal(ADS_ATTR_RFC2307_UIDNUMBER_OID, oids_out[i]) ||
 333                     strequal(ADS_ATTR_SFU_UIDNUMBER_OID, oids_out[i]) ||
 334                     strequal(ADS_ATTR_SFU20_UIDNUMBER_OID, oids_out[i])) {
 335                         schema->posix_uidnumber_attr = talloc_strdup(schema, names_out[i]);
 336                         continue;                      
 337                 }
 338 
 339                 if (strequal(ADS_ATTR_RFC2307_GIDNUMBER_OID, oids_out[i]) ||
 340                     strequal(ADS_ATTR_SFU_GIDNUMBER_OID, oids_out[i]) ||
 341                     strequal(ADS_ATTR_SFU20_GIDNUMBER_OID, oids_out[i])) {
 342                         schema->posix_gidnumber_attr = talloc_strdup(schema, names_out[i]);
 343                         continue;               
 344                 }
 345 
 346                 if (strequal(ADS_ATTR_RFC2307_HOMEDIR_OID, oids_out[i]) ||
 347                     strequal(ADS_ATTR_SFU_HOMEDIR_OID, oids_out[i]) ||
 348                     strequal(ADS_ATTR_SFU20_HOMEDIR_OID, oids_out[i])) {
 349                         schema->posix_homedir_attr = talloc_strdup(schema, names_out[i]);
 350                         continue;                       
 351                 }
 352 
 353                 if (strequal(ADS_ATTR_RFC2307_SHELL_OID, oids_out[i]) ||
 354                     strequal(ADS_ATTR_SFU_SHELL_OID, oids_out[i]) ||
 355                     strequal(ADS_ATTR_SFU20_SHELL_OID, oids_out[i])) {
 356                         schema->posix_shell_attr = talloc_strdup(schema, names_out[i]);
 357                         continue;                       
 358                 }
 359 
 360                 if (strequal(ADS_ATTR_RFC2307_GECOS_OID, oids_out[i]) ||
 361                     strequal(ADS_ATTR_SFU_GECOS_OID, oids_out[i]) ||
 362                     strequal(ADS_ATTR_SFU20_GECOS_OID, oids_out[i])) {
 363                         schema->posix_gecos_attr = talloc_strdup(schema, names_out[i]);
 364                 }
 365 
 366                 if (strequal(ADS_ATTR_RFC2307_UID_OID, oids_out[i]) ||
 367                     strequal(ADS_ATTR_SFU_UID_OID, oids_out[i]) ||
 368                     strequal(ADS_ATTR_SFU20_UID_OID, oids_out[i])) {
 369                         schema->posix_uid_attr = talloc_strdup(schema, names_out[i]);
 370                 }
 371         }
 372 
 373         if (!schema->posix_uidnumber_attr ||
 374             !schema->posix_gidnumber_attr ||
 375             !schema->posix_homedir_attr ||
 376             !schema->posix_shell_attr ||
 377             !schema->posix_gecos_attr) {
 378                 status = ADS_ERROR(LDAP_NO_MEMORY);
 379                 TALLOC_FREE( schema );          
 380                 goto done;
 381         }
 382 
 383         *s = schema;
 384         
 385         status = ADS_ERROR(LDAP_SUCCESS);
 386         
 387 done:
 388         TALLOC_FREE(ctx);
 389 
 390         return status;
 391 }
 392 
 393 #endif

/* [<][>][^][v][top][bottom][index][help] */