summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/passdb/pdb_ldap.c132
-rw-r--r--source3/passdb/secrets.c32
2 files changed, 120 insertions, 44 deletions
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index 46b464a588..55ce8bab36 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -77,36 +77,65 @@ static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_s
/*******************************************************************
find the ldap password
******************************************************************/
-static BOOL fetch_ldapsam_pw(char *dn, char* pw, int len)
+static BOOL fetch_ldapsam_pw(char **dn, char** pw)
{
- fstring key;
- char *p;
- void *data = NULL;
+ char *key = NULL;
size_t size;
- pstrcpy(key, dn);
- for (p=key; *p; p++)
- if (*p == ',') *p = '/';
+ *dn = smb_xstrdup(lp_ldap_admin_dn());
- data=secrets_fetch(key, &size);
- if (!size) {
- DEBUG(0,("fetch_ldap_pw: no ldap secret retrieved!\n"));
- return False;
+ if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
+ SAFE_FREE(*dn);
+ DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
}
- if (size > len-1)
- {
- DEBUG(0,("fetch_ldap_pw: ldap secret is too long (%d > %d)!\n", size, len-1));
- return False;
- }
+ *pw=secrets_fetch(key, &size);
+ if (!size) {
+ /* Upgrade 2.2 style entry */
+ char *p;
+ char* old_style_key = strdup(*dn);
+ char *data;
+ fstring old_style_pw;
+
+ if (!old_style_key) {
+ DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
+ return False;
+ }
+
+ for (p=old_style_key; *p; p++)
+ if (*p == ',') *p = '/';
+
+ data=secrets_fetch(old_style_key, &size);
+ if (!size && size < sizeof(old_style_pw)) {
+ DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
+ SAFE_FREE(old_style_key);
+ SAFE_FREE(*dn);
+ return False;
+ }
+
+ strncpy(old_style_pw, data, size);
+ old_style_pw[size] = 0;
+
+ SAFE_FREE(data);
+
+ if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
+ DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
+ SAFE_FREE(old_style_key);
+ SAFE_FREE(*dn);
+ return False;
+ }
+ if (!secrets_delete(old_style_key)) {
+ DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
+ }
- memcpy(pw, data, size);
- pw[size] = '\0';
+ SAFE_FREE(old_style_key);
+
+ *pw = smb_xstrdup(old_style_pw);
+ }
return True;
}
-
/*******************************************************************
open a connection to the ldap server.
******************************************************************/
@@ -210,20 +239,57 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
return True;
}
+
+/*******************************************************************
+ Add a rebind function for authenticated referrals
+******************************************************************/
+
+static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
+ int *method, int freeit )
+{
+ int rc;
+ char *ldap_dn;
+ char *ldap_secret;
+
+ /** @TODO Should we be doing something to check what servers we rebind to?
+ Could we get a referral to a machine that we don't want to give our
+ username and password to? */
+
+ if (freeit != 0)
+ {
+
+ if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
+ {
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
+ return LDAP_OPERATIONS_ERROR; /* No idea what to return */
+ }
+
+ DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
+ ldap_dn));
+
+ rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
+
+ SAFE_FREE(ldap_dn);
+ SAFE_FREE(ldap_secret);
+
+ return rc;
+ }
+ return 0;
+}
+
/*******************************************************************
connect to the ldap server under system privilege.
******************************************************************/
static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
{
int rc;
- static BOOL got_pw = False;
- static pstring ldap_secret;
+ char *ldap_dn;
+ char *ldap_secret;
- /* get the password if we don't have it already */
- if (!got_pw && !(got_pw=fetch_ldapsam_pw(lp_ldap_admin_dn(), ldap_secret, sizeof(pstring))))
+ /* get the password */
+ if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
{
- DEBUG(0, ("ldap_connect_system: Failed to retrieve password for %s from secrets.tdb\n",
- lp_ldap_admin_dn()));
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
return False;
}
@@ -231,16 +297,22 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l
(OpenLDAP) doesnt' seem to support it */
DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
- lp_ldap_admin_dn()));
-
- if ((rc = ldap_simple_bind_s(ldap_struct, lp_ldap_admin_dn(),
- ldap_secret)) != LDAP_SUCCESS)
+ ldap_dn));
+
+ ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc));
+
+ rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
+
+ SAFE_FREE(ldap_dn);
+ SAFE_FREE(ldap_secret);
+
+ if (rc != LDAP_SUCCESS)
{
DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
return False;
}
- DEBUG(2, ("ldap_connect_system: successful connection to the LDAP server\n"));
+ DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
return True;
}
diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c
index 43fc3604a0..38e78df9d7 100644
--- a/source3/passdb/secrets.c
+++ b/source3/passdb/secrets.c
@@ -52,7 +52,7 @@ BOOL secrets_init(void)
/* read a entry from the secrets database - the caller must free the result
if size is non-null then the size of the entry is put in there
*/
-void *secrets_fetch(char *key, size_t *size)
+void *secrets_fetch(const char *key, size_t *size)
{
TDB_DATA kbuf, dbuf;
secrets_init();
@@ -68,7 +68,7 @@ void *secrets_fetch(char *key, size_t *size)
/* store a secrets entry
*/
-BOOL secrets_store(char *key, void *data, size_t size)
+BOOL secrets_store(const char *key, void *data, size_t size)
{
TDB_DATA kbuf, dbuf;
secrets_init();
@@ -84,7 +84,7 @@ BOOL secrets_store(char *key, void *data, size_t size)
/* delete a secets database entry
*/
-BOOL secrets_delete(char *key)
+BOOL const secrets_delete(const char *key)
{
TDB_DATA kbuf;
secrets_init();
@@ -136,7 +136,7 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid)
*
* @return stored password's key
**/
-char *trust_keystr(char *domain)
+const char *trust_keystr(const char *domain)
{
static fstring keystr;
@@ -154,7 +154,7 @@ char *trust_keystr(char *domain)
*
* @return stored password's key
**/
-char *trustdom_keystr(char *domain)
+char *trustdom_keystr(const char *domain)
{
static char* keystr;
@@ -325,7 +325,7 @@ char *secrets_fetch_machine_password(void)
Routine to delete the machine trust account password file for a domain.
************************************************************************/
-BOOL trust_password_delete(char *domain)
+BOOL trust_password_delete(const char *domain)
{
return secrets_delete(trust_keystr(domain));
}
@@ -333,7 +333,7 @@ BOOL trust_password_delete(char *domain)
/************************************************************************
Routine to delete the password for trusted domain
************************************************************************/
-BOOL trusted_domain_password_delete(char *domain)
+BOOL trusted_domain_password_delete(const char *domain)
{
return secrets_delete(trustdom_keystr(domain));
}
@@ -370,16 +370,20 @@ void reset_globals_after_fork(void)
generate_random_buffer( &dummy, 1, True);
}
-BOOL secrets_store_ldap_pw(char* dn, char* pw)
+BOOL secrets_store_ldap_pw(const char* dn, char* pw)
{
- fstring key;
- char *p;
+ char *key = NULL;
+ BOOL ret;
- pstrcpy(key, dn);
- for (p=key; *p; p++)
- if (*p == ',') *p = '/';
+ if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
+ DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
+ return False;
+ }
+
+ ret = secrets_store(key, pw, strlen(pw)+1);
- return secrets_store(key, pw, strlen(pw));
+ SAFE_FREE(key);
+ return ret;
}