summaryrefslogtreecommitdiff
path: root/source3/passdb/pdb_ldap.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/passdb/pdb_ldap.c')
-rw-r--r--source3/passdb/pdb_ldap.c279
1 files changed, 96 insertions, 183 deletions
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index fd5ad7ee12..02bb43b7ff 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -24,10 +24,7 @@
#include "includes.h"
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
-
-#ifdef HAVE_LDAP
+#ifdef WITH_LDAP_SAM
/* TODO:
* persistent connections: if using NSS LDAP, many connections are made
* however, using only one within Samba would be nice
@@ -75,77 +72,55 @@ struct ldapsam_privates {
static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state);
/*******************************************************************
+ Converts NT user RID to a UNIX uid.
+ ********************************************************************/
+
+static uid_t pdb_user_rid_to_uid(uint32 user_rid)
+{
+ return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
+}
+
+/*******************************************************************
+ converts UNIX uid to an NT User RID.
+ ********************************************************************/
+
+static uint32 pdb_uid_to_user_rid(uid_t uid)
+{
+ return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE);
+}
+
+/*******************************************************************
find the ldap password
******************************************************************/
-static BOOL fetch_ldapsam_pw(char **dn, char** pw)
+static BOOL fetch_ldapsam_pw(char *dn, char* pw, int len)
{
- char *key = NULL;
+ fstring key;
+ char *p;
+ void *data = NULL;
size_t size;
- *dn = smb_xstrdup(lp_ldap_admin_dn());
-
- if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
- SAFE_FREE(*dn);
- DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
- }
+ pstrcpy(key, dn);
+ for (p=key; *p; p++)
+ if (*p == ',') *p = '/';
- *pw=secrets_fetch(key, &size);
+ data=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 = '/';
+ DEBUG(0,("fetch_ldap_pw: no ldap secret retrieved!\n"));
+ return False;
+ }
- 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"));
- }
-
- SAFE_FREE(old_style_key);
-
- *pw = smb_xstrdup(old_style_pw);
+ if (size > len-1)
+ {
+ DEBUG(0,("fetch_ldap_pw: ldap secret is too long (%d > %d)!\n", size, len-1));
+ return False;
}
+
+ memcpy(pw, data, size);
+ pw[size] = '\0';
return True;
}
-static const char *attr[] = {"uid", "pwdLastSet", "logonTime",
- "logoffTime", "kickoffTime", "cn",
- "pwdCanChange", "pwdMustChange",
- "displayName", "homeDrive",
- "smbHome", "scriptPath",
- "profilePath", "description",
- "userWorkstations", "rid",
- "primaryGroupID", "lmPassword",
- "ntPassword", "acctFlags",
- "domain", "description", NULL };
/*******************************************************************
open a connection to the ldap server.
@@ -250,57 +225,20 @@ 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;
- char *ldap_dn;
- char *ldap_secret;
+ static BOOL got_pw = False;
+ static pstring ldap_secret;
- /* get the password */
- if (!fetch_ldapsam_pw(&ldap_dn, &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))))
{
- DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password for %s from secrets.tdb\n",
+ lp_ldap_admin_dn()));
return False;
}
@@ -308,16 +246,10 @@ 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",
- 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)
+ lp_ldap_admin_dn()));
+
+ if ((rc = ldap_simple_bind_s(ldap_struct, lp_ldap_admin_dn(),
+ ldap_secret)) != LDAP_SUCCESS)
{
DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
return False;
@@ -337,7 +269,7 @@ static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, LDAP *
DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter));
- rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, attr, 0, result);
+ rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, NULL, 0, result);
if (rc != LDAP_SUCCESS) {
DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n",
@@ -415,7 +347,7 @@ static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state,
if (rc != LDAP_SUCCESS)
rc = ldapsam_search_one_user_by_uid(ldap_state, ldap_struct,
- fallback_pdb_user_rid_to_uid(rid),
+ pdb_user_rid_to_uid(rid),
result);
return rc;
@@ -425,7 +357,7 @@ static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state,
search an attribute and return the first value found.
******************************************************************/
static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
- char *attribute, pstring value)
+ char *attribute, char *value)
{
char **values;
@@ -589,14 +521,10 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
get_single_attribute(ldap_struct, entry, "rid", temp);
user_rid = (uint32)atol(temp);
-
- pdb_set_user_sid_from_rid(sampass, user_rid);
-
if (!get_single_attribute(ldap_struct, entry, "primaryGroupID", temp)) {
group_rid = 0;
} else {
group_rid = (uint32)atol(temp);
- pdb_set_group_sid_from_rid(sampass, group_rid);
}
if ((ldap_state->permit_non_unix_accounts)
@@ -611,14 +539,12 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pw = getpwnam_alloc(username);
if (pw == NULL) {
- DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username));
+ DEBUG (2,("init_sam_from_ldap: User [%s] does not ave a uid!\n", username));
return False;
}
uid = pw->pw_uid;
gid = pw->pw_gid;
- pdb_set_unix_homedir(sampass, pw->pw_dir);
-
passwd_free(&pw);
pdb_set_uid(sampass, uid);
@@ -628,10 +554,10 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
GROUP_MAP map;
/* call the mapping code here */
if(get_group_map_from_gid(gid, &map, MAPPING_WITHOUT_PRIV)) {
- pdb_set_group_sid(sampass, &map.sid);
+ sid_peek_rid(&map.sid, &group_rid);
}
else {
- pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid));
+ group_rid=pdb_gid_to_group_rid(gid);
}
}
}
@@ -695,41 +621,37 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
}
if (!get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive)) {
- pdb_set_dir_drive(sampass, standard_sub_specified(sampass->mem_ctx,
- lp_logon_drive(),
- username, domain,
- uid, gid),
- False);
+ pstrcpy(dir_drive, lp_logon_drive());
+ standard_sub_advanced(-1, username, "", gid, username, dir_drive);
+ DEBUG(5,("homeDrive fell back to %s\n",dir_drive));
+ pdb_set_dir_drive(sampass, dir_drive, False);
} else {
pdb_set_dir_drive(sampass, dir_drive, True);
}
if (!get_single_attribute(ldap_struct, entry, "smbHome", homedir)) {
- pdb_set_homedir(sampass, standard_sub_specified(sampass->mem_ctx,
- lp_logon_home(),
- username, domain,
- uid, gid),
- False);
+ pstrcpy(homedir, lp_logon_home());
+ standard_sub_advanced(-1, username, "", gid, username, homedir);
+ DEBUG(5,("smbHome fell back to %s\n",homedir));
+ pdb_set_homedir(sampass, homedir, False);
} else {
pdb_set_homedir(sampass, homedir, True);
}
if (!get_single_attribute(ldap_struct, entry, "scriptPath", logon_script)) {
- pdb_set_logon_script(sampass, standard_sub_specified(sampass->mem_ctx,
- lp_logon_script(),
- username, domain,
- uid, gid),
- False);
+ pstrcpy(logon_script, lp_logon_script());
+ standard_sub_advanced(-1, username, "", gid, username, logon_script);
+ DEBUG(5,("scriptPath fell back to %s\n",logon_script));
+ pdb_set_logon_script(sampass, logon_script, False);
} else {
pdb_set_logon_script(sampass, logon_script, True);
}
if (!get_single_attribute(ldap_struct, entry, "profilePath", profile_path)) {
- pdb_set_profile_path(sampass, standard_sub_specified(sampass->mem_ctx,
- lp_logon_path(),
- username, domain,
- uid, gid),
- False);
+ pstrcpy(profile_path, lp_logon_path());
+ standard_sub_advanced(-1, username, "", gid, username, profile_path);
+ DEBUG(5,("profilePath fell back to %s\n",profile_path));
+ pdb_set_profile_path(sampass, profile_path, False);
} else {
pdb_set_profile_path(sampass, profile_path, True);
}
@@ -784,6 +706,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_hours_len(sampass, hours_len);
pdb_set_logon_divs(sampass, logon_divs);
+ pdb_set_user_rid(sampass, user_rid);
+ pdb_set_group_rid(sampass, group_rid);
+
pdb_set_username(sampass, username);
pdb_set_domain(sampass, domain);
@@ -829,7 +754,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
if ( pdb_get_user_rid(sampass) ) {
rid = pdb_get_user_rid(sampass);
} else if (IS_SAM_SET(sampass, FLAG_SAM_UID)) {
- rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass));
+ rid = pdb_uid_to_user_rid(pdb_get_uid(sampass));
} else if (ldap_state->permit_non_unix_accounts) {
rid = ldapsam_get_next_available_nua_rid(ldap_state);
if (rid == 0) {
@@ -1007,7 +932,7 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap
DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter));
rc = ldap_search_s(ldap_struct, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, final_filter, attr, 0,
+ LDAP_SCOPE_SUBTREE, final_filter, NULL, 0,
&result);
if (rc != LDAP_SUCCESS)
@@ -1048,10 +973,6 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap
}
ldap_msgfree(result);
-
- if (top_rid < ldap_state->low_nua_rid)
- top_rid = ldap_state->low_nua_rid;
-
return top_rid;
}
@@ -1085,9 +1006,9 @@ static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_s
/**********************************************************************
Connect to LDAP server for password enumeration
*********************************************************************/
-static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
+static BOOL ldapsam_setsampwent(struct pdb_context *context, BOOL update)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
int rc;
pstring filter;
@@ -1105,7 +1026,7 @@ static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
all_string_sub(filter, "%u", "*", sizeof(pstring));
rc = ldap_search_s(ldap_state->ldap_struct, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter, attr, 0,
+ LDAP_SCOPE_SUBTREE, filter, NULL, 0,
&ldap_state->result);
if (rc != LDAP_SUCCESS)
@@ -1133,9 +1054,9 @@ static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
/**********************************************************************
End enumeration of the LDAP password list
*********************************************************************/
-static void ldapsam_endsampwent(struct pdb_methods *my_methods)
+static void ldapsam_endsampwent(struct pdb_context *context)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
if (ldap_state->ldap_struct && ldap_state->result)
{
ldap_msgfree(ldap_state->result);
@@ -1148,9 +1069,9 @@ static void ldapsam_endsampwent(struct pdb_methods *my_methods)
/**********************************************************************
Get the next entry in the LDAP password database
*********************************************************************/
-static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * user)
+static BOOL ldapsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT * user)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
BOOL ret = False;
while (!ret) {
@@ -1172,9 +1093,9 @@ static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * us
/**********************************************************************
Get SAM_ACCOUNT entry from LDAP by username
*********************************************************************/
-static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const char *sname)
+static BOOL ldapsam_getsampwnam(struct pdb_context *context, SAM_ACCOUNT * user, const char *sname)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
LDAP *ldap_struct;
LDAPMessage *result;
LDAPMessage *entry;
@@ -1223,9 +1144,9 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us
/**********************************************************************
Get SAM_ACCOUNT entry from LDAP by rid
*********************************************************************/
-static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, uint32 rid)
+static BOOL ldapsam_getsampwrid(struct pdb_context *context, SAM_ACCOUNT * user, uint32 rid)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
LDAP *ldap_struct;
LDAPMessage *result;
LDAPMessage *entry;
@@ -1275,20 +1196,12 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
}
}
-static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
-{
- uint32 rid;
- if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
- return False;
- return ldapsam_getsampwrid(my_methods, user, rid);
-}
-
/**********************************************************************
Delete entry from LDAP for username
*********************************************************************/
-static BOOL ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
+static BOOL ldapsam_delete_sam_account(struct pdb_context *context, const SAM_ACCOUNT * sam_acct)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
const char *sname;
int rc;
char *dn;
@@ -1346,9 +1259,9 @@ static BOOL ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOU
/**********************************************************************
Update SAM_ACCOUNT
*********************************************************************/
-static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
+static BOOL ldapsam_update_sam_account(struct pdb_context *context, const SAM_ACCOUNT * newpwd)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
int rc;
char *dn;
LDAP *ldap_struct;
@@ -1413,9 +1326,9 @@ static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOU
/**********************************************************************
Add SAM_ACCOUNT to LDAP
*********************************************************************/
-static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
+static BOOL ldapsam_add_sam_account(struct pdb_context *context, const SAM_ACCOUNT * newpwd)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
int rc;
pstring filter;
LDAP *ldap_struct = NULL;
@@ -1550,7 +1463,7 @@ NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, co
(*pdb_method)->endsampwent = ldapsam_endsampwent;
(*pdb_method)->getsampwent = ldapsam_getsampwent;
(*pdb_method)->getsampwnam = ldapsam_getsampwnam;
- (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
+ (*pdb_method)->getsampwrid = ldapsam_getsampwrid;
(*pdb_method)->add_sam_account = ldapsam_add_sam_account;
(*pdb_method)->update_sam_account = ldapsam_update_sam_account;
(*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
@@ -1598,9 +1511,9 @@ NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method
return NT_STATUS_UNSUCCESSFUL;
}
- ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
+ ldap_state->low_nua_rid=pdb_uid_to_user_rid(low_nua_uid);
- ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
+ ldap_state->high_nua_rid=pdb_uid_to_user_rid(high_nua_uid);
return NT_STATUS_OK;
}
@@ -1610,13 +1523,13 @@ NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method
NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
{
- DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n"));
+ DEBUG(0, ("ldapsam not compiled in!\n"));
return NT_STATUS_UNSUCCESSFUL;
}
NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
{
- DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n"));
+ DEBUG(0, ("ldapsam_nua not compiled in!\n"));
return NT_STATUS_UNSUCCESSFUL;
}