Add smbldap_pull_sid
[ira/wip.git] / source3 / lib / smbldap.c
index f5e152bb959f0ce9b5421a01069a7ed968c3be28..b6921c329c0301af3edb51795d4fbf0f19271b6a 100644 (file)
@@ -333,6 +333,82 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
        return result;
 }
 
+ char * smbldap_talloc_smallest_attribute(LDAP *ldap_struct, LDAPMessage *entry,
+                                         const char *attribute,
+                                         TALLOC_CTX *mem_ctx)
+{
+       char **values;
+       char *result;
+       size_t converted_size;
+       int i, num_values;
+
+       if (attribute == NULL) {
+               return NULL;
+       }
+
+       values = ldap_get_values(ldap_struct, entry, attribute);
+
+       if (values == NULL) {
+               DEBUG(10, ("attribute %s does not exist\n", attribute));
+               return NULL;
+       }
+
+       if (!pull_utf8_talloc(mem_ctx, &result, values[0], &converted_size)) {
+               DEBUG(10, ("pull_utf8_talloc failed\n"));
+               ldap_value_free(values);
+               return NULL;
+       }
+
+       num_values = ldap_count_values(values);
+
+       for (i=1; i<num_values; i++) {
+               char *tmp;
+
+               if (!pull_utf8_talloc(mem_ctx, &tmp, values[i],
+                                     &converted_size)) {
+                       DEBUG(10, ("pull_utf8_talloc failed\n"));
+                       TALLOC_FREE(result);
+                       ldap_value_free(values);
+                       return NULL;
+               }
+
+               if (StrCaseCmp(tmp, result) < 0) {
+                       TALLOC_FREE(result);
+                       result = tmp;
+               } else {
+                       TALLOC_FREE(tmp);
+               }
+       }
+
+       ldap_value_free(values);
+
+#ifdef DEBUG_PASSWORDS
+       DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
+                    attribute, result));
+#endif
+       return result;
+}
+
+ bool smbldap_pull_sid(LDAP *ld, LDAPMessage *msg, const char *attrib,
+                      struct dom_sid *sid)
+{
+       struct berval **values;
+       bool ret = False;
+
+       values = ldap_get_values_len(ld, msg, attrib);
+
+       if (!values) {
+               return false;
+       }
+
+       if (values[0] != NULL) {
+               ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid);
+       }
+
+       ldap_value_free_len(values);
+       return ret;
+}
+
  static int ldapmsg_destructor(LDAPMessage **result) {
        ldap_msgfree(*result);
        return 0;
@@ -444,12 +520,15 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
                        /* notreached. */
                }
 
-               if (!push_utf8_allocate(&utf8_value, value, &converted_size)) {
+               if (!push_utf8_talloc(talloc_tos(), &utf8_value, value, &converted_size)) {
                        smb_panic("smbldap_set_mod: String conversion failure!");
                        /* notreached. */
                }
-
-               mods[i]->mod_values[j] = utf8_value;
+               
+               
+               mods[i]->mod_values[j] = SMB_STRDUP(utf8_value);
+               TALLOC_FREE(utf8_value);
+               SMB_ASSERT(mods[i]->mod_values[j] != NULL);
 
                mods[i]->mod_values[j + 1] = NULL;
        }
@@ -581,7 +660,9 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state)
 
 int smb_ldap_start_tls(LDAP *ldap_struct, int version)
 { 
+#ifdef LDAP_OPT_X_TLS
        int rc;
+#endif
        
        if (lp_ldap_ssl() != LDAP_SSL_START_TLS) {
                return LDAP_SUCCESS;
@@ -1014,7 +1095,7 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
 
 static void smbldap_idle_fn(struct event_context *event_ctx,
                            struct timed_event *te,
-                           const struct timeval *now,
+                           struct timeval now,
                            void *private_data);
 
 /**********************************************************************
@@ -1025,13 +1106,6 @@ static int smbldap_open(struct smbldap_state *ldap_state)
        int rc, opt_rc;
        bool reopen = False;
        SMB_ASSERT(ldap_state);
-               
-#ifndef NO_LDAP_SECURITY
-       if (geteuid() != 0) {
-               DEBUG(0, ("smbldap_open: cannot access LDAP when not root\n"));
-               return  LDAP_INSUFFICIENT_ACCESS;
-       }
-#endif
 
        if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
 
@@ -1086,7 +1160,7 @@ static int smbldap_open(struct smbldap_state *ldap_state)
                ldap_state->idle_event = event_add_timed(
                        ldap_state->event_context, NULL,
                        timeval_current_ofs(SMBLDAP_IDLE_TIME, 0),
-                       "smbldap_idle_fn", smbldap_idle_fn, ldap_state);
+                       smbldap_idle_fn, ldap_state);
        }
 
        DEBUG(4,("The LDAP server is successfully connected\n"));
@@ -1233,7 +1307,7 @@ static int smbldap_search_ext(struct smbldap_state *ldap_state,
                ZERO_STRUCT(ldap_state->last_rebind);
        }
 
-       if (!push_utf8_allocate(&utf8_filter, filter, &converted_size)) {
+       if (!push_utf8_talloc(talloc_tos(), &utf8_filter, filter, &converted_size)) {
                return LDAP_NO_MEMORY;
        }
 
@@ -1281,7 +1355,7 @@ static int smbldap_search_ext(struct smbldap_state *ldap_state,
                }
        }
 
-       SAFE_FREE(utf8_filter);
+       TALLOC_FREE(utf8_filter);
 
        /* Teardown timeout. */
        CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
@@ -1405,7 +1479,7 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
 
        DEBUG(5,("smbldap_modify: dn => [%s]\n", dn ));
 
-       if (!push_utf8_allocate(&utf8_dn, dn, &converted_size)) {
+       if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
                return LDAP_NO_MEMORY;
        }
 
@@ -1433,7 +1507,7 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
                }
        }
                
-       SAFE_FREE(utf8_dn);
+       TALLOC_FREE(utf8_dn);
        return rc;
 }
 
@@ -1449,7 +1523,7 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
 
        DEBUG(5,("smbldap_add: dn => [%s]\n", dn ));
 
-       if (!push_utf8_allocate(&utf8_dn, dn, &converted_size)) {
+       if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
                return LDAP_NO_MEMORY;
        }
 
@@ -1477,7 +1551,7 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
                }
        }
        
-       SAFE_FREE(utf8_dn);
+       TALLOC_FREE(utf8_dn);
        return rc;
 }
 
@@ -1493,7 +1567,7 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
 
        DEBUG(5,("smbldap_delete: dn => [%s]\n", dn ));
 
-       if (!push_utf8_allocate(&utf8_dn, dn, &converted_size)) {
+       if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
                return LDAP_NO_MEMORY;
        }
 
@@ -1521,7 +1595,7 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
                }
        }
        
-       SAFE_FREE(utf8_dn);
+       TALLOC_FREE(utf8_dn);
        return rc;
 }
 
@@ -1579,7 +1653,7 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state,
 
 static void smbldap_idle_fn(struct event_context *event_ctx,
                            struct timed_event *te,
-                           const struct timeval *now,
+                           struct timeval now,
                            void *private_data)
 {
        struct smbldap_state *state = (struct smbldap_state *)private_data;
@@ -1591,13 +1665,13 @@ static void smbldap_idle_fn(struct event_context *event_ctx,
                return;
        }
                
-       if ((state->last_use+SMBLDAP_IDLE_TIME) > now->tv_sec) {
+       if ((state->last_use+SMBLDAP_IDLE_TIME) > now.tv_sec) {
                DEBUG(10,("ldap connection not idle...\n"));
 
                state->idle_event = event_add_timed(
                        event_ctx, NULL,
-                       timeval_add(now, SMBLDAP_IDLE_TIME, 0),
-                       "smbldap_idle_fn", smbldap_idle_fn,
+                       timeval_add(&now, SMBLDAP_IDLE_TIME, 0),
+                       smbldap_idle_fn,
                        private_data);
                return;
        }
@@ -1654,41 +1728,19 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx,
        return NT_STATUS_OK;
 }
 
-/*******************************************************************
- Return a copy of the DN for a LDAPMessage. Convert from utf8 to CH_UNIX.
-********************************************************************/
-char *smbldap_get_dn(LDAP *ld, LDAPMessage *entry)
-{
-       char *utf8_dn, *unix_dn;
-       size_t converted_size;
-
-       utf8_dn = ldap_get_dn(ld, entry);
-       if (!utf8_dn) {
-               DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n"));
-               return NULL;
-       }
-       if (!pull_utf8_allocate(&unix_dn, utf8_dn, &converted_size)) {
-               DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 "
-                          "[%s]\n", utf8_dn));
-               return NULL;
-       }
-       ldap_memfree(utf8_dn);
-       return unix_dn;
-}
-
- const char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld,
-                              LDAPMessage *entry)
+ char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld,
+                        LDAPMessage *entry)
 {
        char *utf8_dn, *unix_dn;
        size_t converted_size;
 
        utf8_dn = ldap_get_dn(ld, entry);
        if (!utf8_dn) {
-               DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n"));
+               DEBUG (5, ("smbldap_talloc_dn: ldap_get_dn failed\n"));
                return NULL;
        }
        if (!pull_utf8_talloc(mem_ctx, &unix_dn, utf8_dn, &converted_size)) {
-               DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 "
+               DEBUG (0, ("smbldap_talloc_dn: String conversion failure utf8 "
                           "[%s]\n", utf8_dn));
                return NULL;
        }