r10656: BIG merge from trunk. Features not copied over
[vlendec/samba-autobuild/.git] / source3 / libads / ldap.c
index 7a59da5a6d363f79971fbfdaeac470e47a0ec80b..bf402b3499e27dafc3d74948579eb141e1bf5b07 100644 (file)
@@ -1703,7 +1703,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res,
                        ldap_memfree(utf8_field);
                }
                ber_free(b, 0);
-               talloc_destroy_pool(ctx);
+               talloc_free_children(ctx);
                fn(NULL, NULL, data_area); /* completed an entry */
 
        }
@@ -2104,7 +2104,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads,
        if ((*num_strings) != range_start) {
                DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu"
                          " - aborting range retreival\n",
-                         range_attr, *num_strings + 1, range_start));
+                         range_attr, (unsigned int)(*num_strings) + 1, range_start));
                ldap_memfree(range_attr);
                *more_strings = False;
                return NULL;
@@ -2140,7 +2140,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads,
                *next_attribute = talloc_asprintf(mem_ctx,
                                                  "%s;range=%d-*", 
                                                  field,
-                                                 *num_strings);
+                                                 (int)*num_strings);
                
                if (!*next_attribute) {
                        DEBUG(1, ("talloc_asprintf for next attribute failed!\n"));
@@ -2388,6 +2388,43 @@ static time_t ads_parse_time(const char *str)
 }
 
 
+const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * OID)
+{
+       ADS_STATUS rc;
+       int count = 0;
+       void *res = NULL;
+       char *expr = NULL;
+       const char *attrs[] = { "lDAPDisplayName", NULL };
+
+       if (ads == NULL || mem_ctx == NULL || OID == NULL) {
+               goto failed;
+       }
+
+       expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", OID);
+       if (expr == NULL) {
+               goto failed;
+       }
+
+       rc = ads_do_search_retry(ads, ads->config.schema_path, 
+                       LDAP_SCOPE_SUBTREE, expr, attrs, &res);
+       if (!ADS_ERR_OK(rc)) {
+               goto failed;
+       }
+
+       count = ads_count_replies(ads, res);
+       if (count == 0 || !res) {
+               goto failed;
+       }
+
+       return ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName");
+       
+failed:
+       DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", 
+               OID));
+       
+       return NULL;
+}
+
 /**
  * Find the servers name and realm - this can be done before authentication 
  *  The ldapServiceName field on w2k  looks like this:
@@ -2397,12 +2434,15 @@ static time_t ads_parse_time(const char *str)
  **/
 ADS_STATUS ads_server_info(ADS_STRUCT *ads)
 {
-       const char *attrs[] = {"ldapServiceName", "currentTime", NULL};
+       const char *attrs[] = {"ldapServiceName", 
+                              "currentTime", 
+                              "schemaNamingContext", NULL};
        ADS_STATUS status;
        void *res;
        char *value;
        char *p;
        char *timestr;
+       char *schema_path;
        TALLOC_CTX *ctx;
 
        if (!(ctx = talloc_init("ads_server_info"))) {
@@ -2429,6 +2469,16 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
                return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
        }
 
+       schema_path = ads_pull_string(ads, ctx, res, "schemaNamingContext");
+       if (!schema_path) {
+               ads_msgfree(ads, res);
+               talloc_destroy(ctx);
+               return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
+       }
+
+       SAFE_FREE(ads->config.schema_path);
+       ads->config.schema_path = SMB_STRDUP(schema_path);
+
        ads_msgfree(ads, res);
 
        p = strchr(value, ':');
@@ -2475,6 +2525,50 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
        return ADS_SUCCESS;
 }
 
+/**
+ * Check for "Services for Unix"-Schema and load some attributes into the ADS_STRUCT
+ * @param ads connection to ads server
+ * @return BOOL status of search (False if one or more attributes couldn't be
+ * found in Active Directory)
+ **/ 
+BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) 
+{ 
+       BOOL ret = False; 
+       TALLOC_CTX *ctx = NULL; 
+       const char *gidnumber, *uidnumber, *homedir, *shell;
+
+       ctx = talloc_init("ads_check_sfu_mapping");
+       if (ctx == NULL)
+               goto done;
+
+       gidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GIDNUMBER_OID);
+       if (gidnumber == NULL)
+               goto done;
+       ads->schema.sfu_gidnumber_attr = SMB_STRDUP(gidnumber);
+
+       uidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_UIDNUMBER_OID);
+       if (uidnumber == NULL)
+               goto done;
+       ads->schema.sfu_uidnumber_attr = SMB_STRDUP(uidnumber);
+
+       homedir = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_HOMEDIR_OID);
+       if (homedir == NULL)
+               goto done;
+       ads->schema.sfu_homedir_attr = SMB_STRDUP(homedir);
+       
+       shell = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_SHELL_OID);
+       if (shell == NULL)
+               goto done;
+       ads->schema.sfu_shell_attr = SMB_STRDUP(shell);
+
+       ret = True;
+done:
+       if (ctx)
+               talloc_destroy(ctx);
+       
+       return ret;
+}
+
 /**
  * find the domain sid for our domain
  * @param ads connection to ads server