diff options
Diffstat (limited to 'source/sam/idmap_ldap.c')
-rw-r--r-- | source/sam/idmap_ldap.c | 576 |
1 files changed, 365 insertions, 211 deletions
diff --git a/source/sam/idmap_ldap.c b/source/sam/idmap_ldap.c index 33cf5fb0302..379f7729abb 100644 --- a/source/sam/idmap_ldap.c +++ b/source/sam/idmap_ldap.c @@ -3,9 +3,10 @@ idmap LDAP backend - Copyright (C) Tim Potter 2000 - Copyright (C) Anthony Liguori 2003 - Copyright (C) Simo Sorce 2003 + Copyright (C) Tim Potter 2000 + Copyright (C) Anthony Liguori 2003 + Copyright (C) Simo Sorce 2003 + Copyright (C) Gerald Carter 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,10 +32,16 @@ #include <lber.h> #include <ldap.h> +#include "smbldap.h" + +#define IDMAP_GROUP_SUFFIX "ou=idmap group" +#define IDMAP_USER_SUFFIX "ou=idmap people" + + struct ldap_idmap_state { LDAP *ldap_struct; time_t last_ping; - const char *uri; + char *uri; char *bind_dn; char *bind_secret; unsigned int num_failures; @@ -53,70 +60,6 @@ static NTSTATUS ldap_idmap_close(void); /******************************************************************* - find the ldap password -******************************************************************/ -static BOOL fetch_ldapsam_pw(char **dn, char** pw) -{ - char *key = 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")); - } - - *pw=secrets_fetch(key, &size); - SAFE_FREE(key); - - 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")); - } - - SAFE_FREE(old_style_key); - - *pw = smb_xstrdup(old_style_pw); - } - - return True; -} - -/******************************************************************* open a connection to the ldap server. ******************************************************************/ static int ldap_idmap_open_connection(struct ldap_idmap_state *state) @@ -284,6 +227,9 @@ static int ldap_idmap_open(struct ldap_idmap_state *state) return LDAP_SUCCESS; } +/******************************************************************* +******************************************************************/ + static int ldap_idmap_retry_open(struct ldap_idmap_state *state, int *attempts) { int rc; @@ -319,6 +265,7 @@ static int ldap_idmap_retry_open(struct ldap_idmap_state *state, int *attempts) a rebind function for authenticated referrals This version takes a void* that we can shove useful stuff in :-) ******************************************************************/ + #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) #else static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, @@ -421,7 +368,7 @@ static int ldap_idmap_connect_system(struct ldap_idmap_state *state) char *ldap_secret; /* get the password */ - if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret)) + if (!fetch_ldap_pw(&ldap_dn, &ldap_secret)) { DEBUG(0, ("ldap_idmap_connect_system: Failed to retrieve " "password from secrets.tdb\n")); @@ -478,9 +425,13 @@ static int ldap_idmap_connect_system(struct ldap_idmap_state *state) return rc; } +/***************************************************************************** + wrapper around ldap_search() +*****************************************************************************/ + static int ldap_idmap_search(struct ldap_idmap_state *state, const char *base, int scope, const char *filter, - const char *attrs[], int attrsonly, + char *attrs[], int attrsonly, LDAPMessage **res) { int rc = LDAP_SERVER_DOWN; @@ -510,9 +461,10 @@ static int ldap_idmap_search(struct ldap_idmap_state *state, return rc; } -/******************************************************************* -search an attribute and return the first value found. -******************************************************************/ +/*********************************************************************** + search an attribute and return the first value found. +***********************************************************************/ + static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state, LDAPMessage * entry, const char *attribute, pstring value) @@ -520,12 +472,16 @@ static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state, char **values; value[0] = '\0'; - if ((values = ldap_get_values (state->ldap_struct, entry, attribute)) - == NULL) { + if ( !entry ) + return False; + + if ((values = ldap_get_values (state->ldap_struct, entry, attribute)) == NULL) + { DEBUG(10,("get_single_attribute: [%s] = [<does not exist>]\n", attribute)); return False; } + if (convert_string(CH_UTF8, CH_UNIX, values[0], -1, value, sizeof(pstring)) == (size_t)-1) @@ -540,9 +496,9 @@ static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state, return True; } -static const char *attrs[] = {"objectClass", "uidNumber", "gidNumber", - "ntSid", NULL}; -static const char *pool_attr[] = {"uidNumber", "gidNumber", NULL}; +/***************************************************************************** + Allocate a new uid or gid +*****************************************************************************/ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) { @@ -552,23 +508,36 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) LDAPMessage *result = 0; LDAPMessage *entry = 0; pstring id_str, new_id_str; - LDAPMod mod[2]; - LDAPMod *mods[3]; - const char *type = (id_type & ID_USERID) ? "uidNumber" : "gidNumber"; - char *val[4]; + LDAPMod **mods = NULL; + const char *type; char *dn; + char **attr_list; + pstring filter; + uid_t luid, huid; + gid_t lgid, hgid; + - rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, "(objectClass=unixIdPool)", - pool_attr, 0, &result); + type = (id_type & ID_USERID) ? + get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) : + get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); + + snprintf(filter, sizeof(filter)-1, "(objectClass=%s)", LDAP_OBJ_IDPOOL); + + attr_list = get_attr_list( idpool_attr_list ); + + rc = ldap_idmap_search(&ldap_state, lp_ldap_idmap_suffix(), + LDAP_SCOPE_SUBTREE, filter, + attr_list, 0, &result); + free_attr_list( attr_list ); + if (rc != LDAP_SUCCESS) { - DEBUG(0,("ldap_allocate_id: unixIdPool object not found\n")); + DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL)); goto out; } count = ldap_count_entries(ldap_state.ldap_struct, result); if (count != 1) { - DEBUG(0,("ldap_allocate_id: single unixIdPool not found\n")); + DEBUG(0,("ldap_allocate_id: single %s object not found\n", LDAP_OBJ_IDPOOL)); goto out; } @@ -580,210 +549,308 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) type)); goto out; } + + /* this must succeed or else we wouldn't have initialized */ + + lp_idmap_uid( &luid, &huid); + lp_idmap_gid( &lgid, &hgid); + + /* make sure we still have room to grow */ + if (id_type & ID_USERID) { id->uid = strtoul(id_str, NULL, 10); - } else { + if (id->uid > huid ) { + DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %d!\n", huid)); + goto out; + } + } + else { id->gid = strtoul(id_str, NULL, 10); + if (id->gid > hgid ) { + DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %d!\n", hgid)); + goto out; + } } - - mod[0].mod_op = LDAP_MOD_DELETE; - mod[0].mod_type = strdup(type); - val[0] = id_str; val[1] = NULL; - mod[0].mod_values = val; - - pstr_sprintf(new_id_str, "%ud", + + snprintf(new_id_str, sizeof(new_id_str), "%u", ((id_type & ID_USERID) ? id->uid : id->gid) + 1); - mod[1].mod_op = LDAP_MOD_ADD; - mod[1].mod_type = strdup(type); - val[3] = new_id_str; val[4] = NULL; - mod[1].mod_values = val + 2; - - mods[0] = mod; mods[1] = mod + 1; mods[2] = NULL; + + ldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str ); + ldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str ); + rc = ldap_modify_s(ldap_state.ldap_struct, dn, mods); - ldap_memfree(dn); - if (rc == LDAP_SUCCESS) ret = NT_STATUS_OK; + ldap_memfree(dn); + ldap_mods_free( mods, True ); + + if (rc != LDAP_SUCCESS) { + DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n", + type)); + goto out; + } + + ret = NT_STATUS_OK; out: return ret; } -/* Get a sid from an id */ +/***************************************************************************** + get a sid from an id +*****************************************************************************/ + static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) { LDAPMessage *result = 0; LDAPMessage *entry = 0; pstring sid_str; pstring filter; - char type = (id_type & ID_USERID) ? 'u' : 'g'; + pstring suffix; + const char *type; int rc; int count; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - pstr_sprintf(filter, "(&(%cidNumber=%ud)(objectClass=sambaAccount))", - type, ((id_type & ID_USERID) ? id.uid : id.gid)); - rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, attrs, 0, - &result); - if (rc != LDAP_SUCCESS) { - goto out; - } + char **attr_list; + + /* first we try for a samba user or group mapping */ + + if ( id_type & ID_USERID ) { + type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ); + snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))", + LDAP_OBJ_SAMBASAMACCOUNT, type, id.uid ); + pstrcpy( suffix, lp_ldap_suffix()); + } + else { + type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); + snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))", + LDAP_OBJ_GROUPMAP, type, id.gid ); + pstrcpy( suffix, lp_ldap_group_suffix() ); + } + + attr_list = get_attr_list( sidmap_attr_list ); + rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE, + filter, attr_list, 0, &result); + if (rc != LDAP_SUCCESS) + goto out; + count = ldap_count_entries(ldap_state.ldap_struct, result); + + /* fall back to looking up an idmap entry if we didn't find and + actual user or group */ + if (count == 0) { - pstr_sprintf(filter, - "(&(objectClass=idmapEntry)(%cidNumber=%ud))", - type, ((id_type & ID_USERID) ? id.uid : id.gid)); - rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, - attrs, 0, &result); - if (rc != LDAP_SUCCESS) { + snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))", + LDAP_OBJ_IDMAP_ENTRY, type, ((id_type & ID_USERID) ? id.uid : id.gid)); + +#if 0 /* commented out for now -- jerry */ + if ( id_type & ID_USERID ) + snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_USER_SUFFIX, lp_ldap_idmap_suffix() ); + else + snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_GROUP_SUFFIX, lp_ldap_idmap_suffix() ); +#else + pstrcpy( suffix, lp_ldap_idmap_suffix() ); +#endif + + rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE, + filter, attr_list, 0, &result); + + if (rc != LDAP_SUCCESS) goto out; - } - count = ldap_count_entries(ldap_state.ldap_struct, result); + + count = ldap_count_entries(ldap_state.ldap_struct, result); } if (count != 1) { - DEBUG(0,("ldap_get_sid_from_id: mapping not found for " - "%cid: %ud\n", (id_type&ID_USERID)?'u':'g', - ((id_type & ID_USERID) ? id.uid : id.gid))); + DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %u\n", + type, ((id_type & ID_USERID) ? id.uid : id.gid))); goto out; } entry = ldap_first_entry(ldap_state.ldap_struct, result); - if (!ldap_idmap_attribute(&ldap_state, entry, "ntSid", sid_str)) { + if ( !ldap_idmap_attribute(&ldap_state, entry, LDAP_ATTRIBUTE_SID, sid_str) ) goto out; - } - if (!string_to_sid(sid, sid_str)) { + if (!string_to_sid(sid, sid_str)) goto out; - } ret = NT_STATUS_OK; out: + free_attr_list( attr_list ); + return ret; } -/* Get an id from a sid */ -static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, - const DOM_SID *sid) +/*********************************************************************** + Get an id from a sid +***********************************************************************/ + +static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid) { LDAPMessage *result = 0; LDAPMessage *entry = 0; pstring sid_str; pstring filter; pstring id_str; - const char *type = (*id_type & ID_USERID) ? "uidNumber" : "gidNumber"; - const char *class = - (*id_type & ID_USERID) ? "sambaAccount" : "sambaGroupMapping"; + pstring suffix; + const char *type; + const char *obj_class; int rc; int count; + char **attr_list; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + /* first try getting the mapping from a samba user or group */ + + if ( *id_type & ID_USERID ) { + type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ); + obj_class = LDAP_OBJ_SAMBASAMACCOUNT; + pstrcpy( suffix, lp_ldap_suffix() ); + } + else { + type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); + obj_class = LDAP_OBJ_GROUPMAP; + pstrcpy( suffix, lp_ldap_group_suffix() ); + } sid_to_string(sid_str, sid); - pstr_sprintf(filter, "(&(objectClass=%s)(ntSid=%s)", class, sid_str); - rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result); - if (rc != LDAP_SUCCESS) { + snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%s))", obj_class, + LDAP_ATTRIBUTE_SID, sid_str); + + attr_list = get_attr_list( sidmap_attr_list ); + rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE, + filter, attr_list, 0, &result); + + if (rc != LDAP_SUCCESS) goto out; - } + count = ldap_count_entries(ldap_state.ldap_struct, result); + + /* fall back to looking up an idmap entry if we didn't find and + actual user or group */ + if (count == 0) { - pstr_sprintf(filter, - "(&(objectClass=idmapEntry)(ntSid=%s))", sid_str); + snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%s))", + LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str); + +#if 0 /* commented out for now -- jerry */ + if ( *id_type & ID_USERID ) + snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_USER_SUFFIX, lp_ldap_idmap_suffix() ); + else + snprintf( suffix, sizeof(suffix), "%s,%s", IDMAP_GROUP_SUFFIX, lp_ldap_idmap_suffix() ); +#else + pstrcpy( suffix, lp_ldap_idmap_suffix() ); +#endif - rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, - attrs, 0, &result); - if (rc != LDAP_SUCCESS) { - goto out; - } - count = ldap_count_entries(ldap_state.ldap_struct, result); + rc = ldap_idmap_search(&ldap_state, suffix, LDAP_SCOPE_SUBTREE, + filter, attr_list, 0, &result); + + if (rc != LDAP_SUCCESS) + goto out; + + count = ldap_count_entries(ldap_state.ldap_struct, result); } - - /* our search filters may 2 objects in the case that a user and group - rid are the same */ - if (count != 1 && count != 2) { - DEBUG(0, - ("ldap_get_id_from_sid: incorrect number of objects\n")); + + if ( count > 1 ) { + DEBUG(0, ("ldap_get_id_from_sid: search %s returned more than on entry!\n", + filter)); goto out; } - entry = ldap_first_entry(ldap_state.ldap_struct, result); - if (!ldap_idmap_attribute(&ldap_state, entry, type, id_str)) { - entry = ldap_next_entry(ldap_state.ldap_struct, entry); - - if (!ldap_idmap_attribute(&ldap_state, entry, type, id_str)) { - int i; + /* we might have an existing entry to work with so pull out the requested information */ + + if ( count ) + entry = ldap_first_entry(ldap_state.ldap_struct, result); + + /* if entry == NULL, then we will default to allocating a new id */ + + if ( !ldap_idmap_attribute(&ldap_state, entry, type, id_str) ) + { + int i; - for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) { - ret = ldap_allocate_id(id, *id_type); - if (NT_STATUS_IS_OK(ret)) { - break; - } - } - if (NT_STATUS_IS_OK(ret)) { - ret = ldap_set_mapping(sid, *id, *id_type); - } else { - DEBUG(0,("ldap_allocate_id: cannot acquire id" - " lock\n")); - } - } else { - if ((*id_type & ID_USERID)) { - id->uid = strtoul(id_str, NULL, 10); - } else { - id->gid = strtoul(id_str, NULL, 10); - } - ret = NT_STATUS_OK; + for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) + { + ret = ldap_allocate_id(id, *id_type); + if ( NT_STATUS_IS_OK(ret) ) + break; } - } else { - if ((*id_type & ID_USERID)) { + + if ( !NT_STATUS_IS_OK(ret) ) { + DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n")); + goto out; + } + + ret = ldap_set_mapping(sid, *id, *id_type); + + } + else + { + if ( (*id_type & ID_USERID) ) id->uid = strtoul(id_str, NULL, 10); - } else { + else id->gid = strtoul(id_str, NULL, 10); - } + ret = NT_STATUS_OK; } out: + free_attr_list( attr_list ); + return ret; } -/* This function cannot be called to modify a mapping, only set a new one */ +/*********************************************************************** + This function cannot be called to modify a mapping, only set a new one +***********************************************************************/ + static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) { pstring dn, sid_str, id_str; - const char *type = (id_type & ID_USERID) ? "uidNumber" : "gidNumber"; - LDAPMod *mods[3]; - LDAPMod mod[2]; - char *val[4]; + fstring type; + LDAPMod **mods = NULL; int rc; int attempts = 0; - pstr_sprintf(id_str, "%ud", ((id_type & ID_USERID) ? id.uid : id.gid)); - sid_to_string(sid_str, sid); - pstr_sprintf(dn, "%s=%ud,%s", type, ((id_type & ID_USERID) ? id.uid : id.gid), lp_ldap_suffix()); - mod[0].mod_op = LDAP_MOD_REPLACE; - mod[0].mod_type = strdup(type); - val[0] = id_str; val[1] = NULL; - mod[0].mod_values = val; + if ( id_type & ID_USERID ) + fstrcpy( type, get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) ); + else + fstrcpy( type, get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ) ); - mod[1].mod_op = LDAP_MOD_REPLACE; - mod[1].mod_type = strdup("ntSid"); - val[2] = sid_str; val[3] = NULL; - mod[1].mod_values = val + 2; +#if 0 + snprintf(dn, sizeof(dn), "%s=%u,%s,%s", type, + ((id_type & ID_USERID) ? id.uid : id.gid), + ((id_type & ID_USERID) ? IDMAP_USER_SUFFIX : IDMAP_GROUP_SUFFIX ), + lp_ldap_idmap_suffix()); +#else + snprintf(dn, sizeof(dn), "%s=%u,%s", type, + ((id_type & ID_USERID) ? id.uid : id.gid), + lp_ldap_idmap_suffix()); +#endif - mods[0] = mod; mods[1] = mod + 1; mods[2] = NULL; + snprintf(id_str, sizeof(id_str), "%u", ((id_type & ID_USERID) ? id.uid : id.gid)); + sid_to_string( sid_str, sid ); + + ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY ); + ldap_set_mod( &mods, LDAP_MOD_ADD, type, id_str ); + ldap_set_mod( &mods, LDAP_MOD_ADD, + get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), sid_str ); do { - if ((rc = ldap_idmap_retry_open(&ldap_state, &attempts)) != - LDAP_SUCCESS) continue; + if ((rc = ldap_idmap_retry_open(&ldap_state, &attempts)) != LDAP_SUCCESS) + continue; - rc = ldap_modify_s(ldap_state.ldap_struct, dn, mods); + rc = ldap_add_s(ldap_state.ldap_struct, dn, mods); } while ((rc == LDAP_SERVER_DOWN) && (attempts <= 8)); + ldap_mods_free( mods, True ); + if (rc != LDAP_SUCCESS) { + DEBUG(0,("ldap_set_mapping: Failed to create mapping from %s to %d [%s]\n", + sid_str, ((id_type & ID_USERID) ? id.uid : id.gid), type)); return NT_STATUS_UNSUCCESSFUL; } + + DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %d [%s]\n", + sid_str, ((id_type & ID_USERID) ? id.uid : id.gid), type)); return NT_STATUS_OK; } @@ -791,21 +858,109 @@ static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) /***************************************************************************** Initialise idmap database. *****************************************************************************/ -static NTSTATUS ldap_idmap_init(void) +static NTSTATUS ldap_idmap_init( char *params ) { - /* We wait for the first search request before we try to connect to - the LDAP server. We may want to connect upon initialization though - -- aliguori */ + fstring filter; +#if 0 + pstring dn; +#endif + int rc; + char **attr_list; + LDAPMessage *result = NULL; + LDAPMod **mods = NULL; + int count; + + /* parse out the server (assuming only parameter is a URI) */ + + if ( params ) + ldap_state.uri = smb_xstrdup( params ); + else + ldap_state.uri = smb_xstrdup( "ldap://localhost/" ); + + /* see if the idmap suffix and sub entries exists */ + + snprintf( filter, sizeof(filter), "(objectclass=%s)", LDAP_OBJ_IDPOOL ); + + attr_list = get_attr_list( idpool_attr_list ); + rc = ldap_idmap_search(&ldap_state, lp_ldap_idmap_suffix(), + LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result); + free_attr_list ( attr_list ); + + if (rc != LDAP_SUCCESS) + return NT_STATUS_UNSUCCESSFUL; + + count = ldap_count_entries(ldap_state.ldap_struct, result); + + if ( count > 1 ) { + DEBUG(0,("ldap_idmap_init: multiple entries returned from %s (base == %s)\n", + filter, lp_ldap_idmap_suffix() )); + return NT_STATUS_UNSUCCESSFUL; + } + else if (count == 0) { + uid_t luid, huid; + gid_t lgid, hgid; + fstring uid_str, gid_str; + int attempts = 0; + + if ( !lp_idmap_uid(&luid, &huid) || !lp_idmap_gid( &lgid, &hgid ) ) { + DEBUG(0,("ldap_idmap_init: idmap uid/gid parameters not specified\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + snprintf( uid_str, sizeof(uid_str), "%d", luid ); + snprintf( gid_str, sizeof(gid_str), "%d", lgid ); + + ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDPOOL ); + ldap_set_mod( &mods, LDAP_MOD_ADD, + get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER), uid_str ); + ldap_set_mod( &mods, LDAP_MOD_ADD, + get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER), gid_str ); + + do { + if ((rc = ldap_idmap_retry_open(&ldap_state, &attempts)) != LDAP_SUCCESS) + continue; + + rc = ldap_modify_s(ldap_state.ldap_struct, lp_ldap_idmap_suffix(), mods); + } while ((rc == LDAP_SERVER_DOWN) && (attempts <= 8)); + } + + /* we have the initial entry now; let's create the sub entries */ + /* if they already exist then this will fail, but we don't care */ + +#if 0 /* commenting out for now, but I will come back to this --jerry */ + + mods = NULL; + snprintf( dn, sizeof(dn), "%s,%s", IDMAP_USER_SUFFIX, lp_ldap_idmap_suffix() ); + ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_OU ); + ldap_set_mod( &mods, LDAP_MOD_ADD, "ou", "idmap people" ); + ldap_add_s(ldap_state.ldap_struct, dn, mods); + ldap_mods_free( mods, True ); + + mods = NULL; + snprintf( dn, sizeof(dn), "%s,%s", IDMAP_GROUP_SUFFIX, lp_ldap_idmap_suffix() ); + ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_OU ); + ldap_set_mod( &mods, LDAP_MOD_ADD, "ou", "idmap group" ); + ldap_add_s(ldap_state.ldap_struct, dn, mods); + ldap_mods_free( mods, True ); +#endif + return NT_STATUS_OK; } -/* End the LDAP session */ +/***************************************************************************** + End the LDAP session +*****************************************************************************/ + static NTSTATUS ldap_idmap_close(void) { if (ldap_state.ldap_struct != NULL) { ldap_unbind_ext(ldap_state.ldap_struct, NULL, NULL); ldap_state.ldap_struct = NULL; } + + SAFE_FREE( ldap_state.uri ); + SAFE_FREE( ldap_state.bind_dn ); + SAFE_FREE( ldap_state.bind_secret ); DEBUG(5,("The connection to the LDAP server was closed\n")); /* maybe free the results here --metze */ @@ -833,6 +988,5 @@ static struct idmap_methods ldap_methods = { NTSTATUS idmap_ldap_init(void) { - DEBUG(0,("idmap_reg_ldap: no LDAP support\n")); return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap", &ldap_methods); } |