diff options
Diffstat (limited to 'source3/passdb/pdb_ldap.c')
-rw-r--r-- | source3/passdb/pdb_ldap.c | 279 |
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; } |