{ 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" },
/*******************************************************************
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;
return False;
}
+ size = MIN(size, sizeof(fstring)-1);
strncpy(old_style_pw, data, size);
old_style_pw[size] = 0;
}
/*******************************************************************
-search an attribute and return the first value found.
+ Search an attribute and return the first value found.
******************************************************************/
+
BOOL smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
const char *attribute, pstring value)
{
return False;
}
- if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, sizeof(pstring)) == (size_t)-1)
- {
+ if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, sizeof(pstring)) == (size_t)-1) {
DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n",
attribute, values[0]));
ldap_value_free(values);
}
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;
}
*modlist = mods;
}
-
/**********************************************************************
Set attribute to newval in LDAP, regardless of what value the
attribute had in LDAP before.
*********************************************************************/
+
void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
LDAPMod ***mods,
const char *attribute, const char *newval)
{
- char **values = NULL;
+ pstring oldval;
+ BOOL existed;
if (existing != NULL) {
- values = ldap_get_values(ldap_struct, existing, attribute);
+ existed = smbldap_get_single_attribute(ldap_struct, existing, attribute, oldval);
+ } else {
+ existed = False;
+ *oldval = '\0';
}
/* all of our string attributes are case insensitive */
- if ((values != NULL) && (values[0] != NULL) &&
- StrCaseCmp(values[0], 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
same... */
-
- ldap_value_free(values);
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. */
if ((newval != NULL) && (strlen(newval) > 0)) {
smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
}
-
- if (values == NULL) {
- /* 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, values[0]);
- ldap_value_free(values);
}
-
/**********************************************************************
Some varients of the LDAP rebind code do not pass in the third 'arg'
pointer to a void*, so we try and work around it by assuming that the
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")) {
}
*methodp = LDAP_AUTH_SIMPLE;
}
+
+ gettimeofday(&(ldap_state->last_rebind),NULL);
+
return 0;
}
#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
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)*/
*/
DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n",
sleep_time));
- msleep(sleep_time);
+ smb_msleep(sleep_time);
}
(*attempts)++;
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;
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;
}
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;
}
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;
}
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) {
&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);
}
LDAPMessage *result = NULL;
int num_result;
char **attr_list;
+ uid_t u_low, u_high;
+ gid_t g_low, g_high;
+ uint32 rid_low, rid_high;
slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))",
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE),
algorithmic_rid_base_string);
smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
+
+ /* add the sambaNext[User|Group]Rid attributes if the idmap ranges are set.
+ TODO: fix all the places where the line between idmap and normal operations
+ needed by smbd gets fuzzy --jerry 2003-08-11 */
+
+ if ( lp_idmap_uid(&u_low, &u_high) && lp_idmap_gid(&g_low, &g_high)
+ && get_free_rid_range(&rid_low, &rid_high) )
+ {
+ fstring rid_str;
+
+ fstr_sprintf( rid_str, "%i", rid_high|USER_RID_TYPE );
+ DEBUG(10,("setting next available user rid [%s]\n", rid_str));
+ smbldap_set_mod(&mods, LDAP_MOD_ADD,
+ get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
+ rid_str);
+
+ fstr_sprintf( rid_str, "%i", rid_high|GROUP_RID_TYPE );
+ DEBUG(10,("setting next available group rid [%s]\n", rid_str));
+ smbldap_set_mod(&mods, LDAP_MOD_ADD,
+ get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
+ rid_str);
+
+ }
+
switch(ldap_op)
{
return ret;
}
+/*******************************************************************
+ 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;
+
+ 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) == (size_t)-1) {
+ DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 [%s]\n", utf8_dn));
+ return NULL;
+ }
+ ldap_memfree(utf8_dn);
+ return unix_dn;
+}