Fix typo.
[samba.git] / source3 / lib / smbldap.c
index 781e6b976c37cf0c4d8a8f624bd74163dde14325..c8305eeb8025f0e9d8814250ec5f55210a2cc797 100644 (file)
@@ -97,10 +97,13 @@ ATTRIB_MAP_ENTRY attrib_map_v30[] = {
        { LDAP_ATTR_DOMAIN,             "sambaDomainName"       },
        { LDAP_ATTR_OBJCLASS,           "objectClass"           },
        { LDAP_ATTR_ACB_INFO,           "sambaAcctFlags"        },
+       { LDAP_ATTR_MUNGED_DIAL,        "sambaMungedDial"       },
+       { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" },
+       { LDAP_ATTR_BAD_PASSWORD_TIME,  "sambaBadPasswordTime"  },
        { LDAP_ATTR_LIST_END,           NULL                    }
 };
 
-/* attributes used for alalocating RIDs */
+/* attributes used for allocating RIDs */
 
 ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
        { LDAP_ATTR_DOMAIN,             "sambaDomainName"       },
@@ -220,7 +223,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
 /*******************************************************************
  find the ldap password
 ******************************************************************/
-BOOL fetch_ldap_pw(char **dn, char** pw)
+static BOOL fetch_ldap_pw(char **dn, char** pw)
 {
        char *key = NULL;
        size_t size;
@@ -258,6 +261,7 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
                        return False;
                }
 
+               size = MIN(size, sizeof(fstring)-1);
                strncpy(old_style_pw, data, size);
                old_style_pw[size] = 0;
 
@@ -350,7 +354,7 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
        }
 
        for (i = 0; mods[i] != NULL; ++i) {
-               if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
+               if (mods[i]->mod_op == modop && strequal(mods[i]->mod_type, attribute))
                        break;
        }
 
@@ -423,7 +427,7 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
 
        /* all of our string attributes are case insensitive */
        
-       if (existed && (StrCaseCmp(oldval, newval) == 0)) {
+       if (existed && newval && (StrCaseCmp(oldval, newval) == 0)) {
                
                /* Believe it or not, but LDAP will deny a delete and
                   an add at the same time if the values are the
@@ -431,6 +435,21 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
                return;
        }
 
+       if (existed) {
+               /* There has been no value before, so don't delete it.
+                * Here's a possible race: We might end up with
+                * duplicate attributes */
+               /* By deleting exactly the value we found in the entry this
+                * should be race-free in the sense that the LDAP-Server will
+                * deny the complete operation if somebody changed the
+                * attribute behind our back. */
+               /* This will also allow modifying single valued attributes 
+                * in Novell NDS. In NDS you have to first remove attribute and then
+                * you could add new value */
+               
+               smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);
+       }
+
        /* Regardless of the real operation (add or modify)
           we add the new value here. We rely on deleting
           the old value, should it exist. */
@@ -438,20 +457,6 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
        if ((newval != NULL) && (strlen(newval) > 0)) {
                smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
        }
-
-       if (!existed) {
-               /* There has been no value before, so don't delete it.
-                  Here's a possible race: We might end up with
-                  duplicate attributes */
-               return;
-       }
-
-       /* By deleting exactly the value we found in the entry this
-          should be race-free in the sense that the LDAP-Server will
-          deny the complete operation if somebody changed the
-          attribute behind our back. */
-
-       smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);
 }
 
 /**********************************************************************
@@ -542,11 +547,11 @@ static int smbldap_open_connection (struct smbldap_state *ldap_state)
                SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
                
                /* skip leading "URL:" (if any) */
-               if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
+               if ( strnequal( p, "URL:", 4 ) ) {
                        p += 4;
                }
                
-               sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
+               sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, host, &port);
                
                if (port == 0) {
                        if (strequal(protocol, "ldap")) {
@@ -659,6 +664,9 @@ static int rebindproc_with_state  (LDAP * ld, char **whop, char **credp,
                }
                *methodp = LDAP_AUTH_SIMPLE;
        }
+
+       gettimeofday(&(ldap_state->last_rebind),NULL);
+               
        return 0;
 }
 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
@@ -685,6 +693,8 @@ static int rebindproc_connect_with_state (LDAP *ldap_struct,
 
        rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
        
+       gettimeofday(&(ldap_state->last_rebind),NULL);
+
        return rc;
 }
 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
@@ -880,7 +890,7 @@ int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts)
                 */
                DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n", 
                          sleep_time));
-               msleep(sleep_time);
+               smb_msleep(sleep_time);
        }
        (*attempts)++;
 
@@ -906,6 +916,32 @@ int smbldap_search(struct smbldap_state *ldap_state,
        char           *utf8_filter;
 
        SMB_ASSERT(ldap_state);
+       
+       DEBUG(5,("smbldap_search: base => [%s], filter => [%s], scope => [%d]\n",
+               base, filter, scope));
+
+       if (ldap_state->last_rebind.tv_sec > 0) {
+               struct timeval  tval;
+               int             tdiff = 0;
+               int             sleep_time = 0;
+
+               ZERO_STRUCT(tval);
+
+               gettimeofday(&tval,NULL);
+
+               tdiff = 1000000 *(tval.tv_sec - ldap_state->last_rebind.tv_sec) + 
+                       (tval.tv_usec - ldap_state->last_rebind.tv_usec);
+
+               sleep_time = ((1000*lp_ldap_replication_sleep())-tdiff)/1000;
+
+               if (sleep_time > 0) {
+                       /* we wait for the LDAP replication */
+                       DEBUG(5,("smbldap_search: waiting %d milliseconds for LDAP replication.\n",sleep_time));
+                       smb_msleep(sleep_time);
+                       DEBUG(5,("smbldap_search: go on!\n"));
+                       ZERO_STRUCT(ldap_state->last_rebind);
+               }
+       }
 
        if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) {
                return LDAP_NO_MEMORY;
@@ -939,6 +975,8 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
 
        SMB_ASSERT(ldap_state);
 
+       DEBUG(5,("smbldap_modify: dn => [%s]\n", dn ));
+
        if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
                return LDAP_NO_MEMORY;
        }
@@ -970,6 +1008,8 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
        
        SMB_ASSERT(ldap_state);
 
+       DEBUG(5,("smbldap_add: dn => [%s]\n", dn ));
+
        if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
                return LDAP_NO_MEMORY;
        }
@@ -1001,6 +1041,8 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
        
        SMB_ASSERT(ldap_state);
 
+       DEBUG(5,("smbldap_delete: dn => [%s]\n", dn ));
+
        if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
                return LDAP_NO_MEMORY;
        }
@@ -1063,8 +1105,6 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter,
        int scope = LDAP_SCOPE_SUBTREE;
        int rc;
 
-       DEBUG(2, ("smbldap_search_suffix: searching for:[%s]\n", filter));
-
        rc = smbldap_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result);
 
        if (rc != LDAP_SUCCESS) {
@@ -1073,8 +1113,6 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter,
                                &ld_error);
                DEBUG(0,("smbldap_search_suffix: Problem during the LDAP search: %s (%s)\n", 
                        ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
-               DEBUG(3,("smbldap_search_suffix: Query was: %s, %s\n", lp_ldap_suffix(), 
-                       filter));
                SAFE_FREE(ld_error);
        }
        
@@ -1340,7 +1378,7 @@ char *smbldap_get_dn(LDAP *ld, LDAPMessage *entry)
                DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n"));
                return NULL;
        }
-       if (pull_utf8_allocate((void **) &unix_dn, utf8_dn) == (size_t)-1) {
+       if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) {
                DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 [%s]\n", utf8_dn));
                return NULL;
        }