diff options
Diffstat (limited to 'source3/sam/idmap_ldap.c')
-rw-r--r-- | source3/sam/idmap_ldap.c | 352 |
1 files changed, 197 insertions, 155 deletions
diff --git a/source3/sam/idmap_ldap.c b/source3/sam/idmap_ldap.c index 9a1ee039d0..6122641718 100644 --- a/source3/sam/idmap_ldap.c +++ b/source3/sam/idmap_ldap.c @@ -4,7 +4,7 @@ idmap LDAP backend Copyright (C) Tim Potter 2000 - Copyright (C) Anthony Liguori 2003 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 Copyright (C) Simo Sorce 2003 Copyright (C) Gerald Carter 2003 @@ -41,12 +41,6 @@ struct ldap_idmap_state { struct smbldap_state *smbldap_state; TALLOC_CTX *mem_ctx; - - uint32 low_allocated_user_rid; - uint32 high_allocated_user_rid; - uint32 low_allocated_group_rid; - uint32 high_allocated_group_rid; - }; #define LDAP_MAX_ALLOC_ID 128 /* number tries while allocating @@ -203,11 +197,7 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), old_rid_string)) { - - *rid = (uint32)atol(old_rid_string); - - } else { - *rid = state->low_allocated_user_rid; + *rid = (uint32)atol(old_rid_string); } break; case GROUP_RID_TYPE: @@ -216,8 +206,6 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, old_rid_string)) { *rid = (uint32)atol(old_rid_string); - } else { - *rid = state->low_allocated_group_rid; } break; } @@ -231,10 +219,6 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, switch (rid_type) { case USER_RID_TYPE: - if (next_rid > state->high_allocated_user_rid) { - return NT_STATUS_UNSUCCESSFUL; - } - /* Try to make the modification atomically by enforcing the old value in the delete mod. */ smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods, @@ -243,10 +227,6 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, break; case GROUP_RID_TYPE: - if (next_rid > state->high_allocated_group_rid) { - return NT_STATUS_UNSUCCESSFUL; - } - /* Try to make the modification atomically by enforcing the old value in the delete mod. */ smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods, @@ -361,7 +341,7 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) 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); + pstr_sprintf(filter, "(objectClass=%s)", LDAP_OBJ_IDPOOL); attr_list = get_attr_list( idpool_attr_list ); @@ -400,20 +380,23 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) if (id_type & ID_USERID) { id->uid = strtoul(id_str, NULL, 10); if (id->uid > huid ) { - DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %d!\n", huid)); + DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %lu!\n", + (unsigned long)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)); + DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %lu!\n", + (unsigned long)hgid)); goto out; } } - snprintf(new_id_str, sizeof(new_id_str), "%u", - ((id_type & ID_USERID) ? id->uid : id->gid) + 1); + pstr_sprintf(new_id_str, "%lu", + ((id_type & ID_USERID) ? (unsigned long)id->uid : + (unsigned long)id->gid) + 1); smbldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str ); smbldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str ); @@ -458,27 +441,38 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) if ( id_type & ID_USERID ) { type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ); obj_class = LDAP_OBJ_SAMBASAMACCOUNT; - snprintf(id_str, sizeof(id_str), "%u", id.uid ); + fstr_sprintf(id_str, "%lu", (unsigned long)id.uid ); pstrcpy( suffix, lp_ldap_suffix()); } else { type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); obj_class = LDAP_OBJ_GROUPMAP; - snprintf(id_str, sizeof(id_str), "%u", id.gid ); + fstr_sprintf(id_str, "%lu", (unsigned long)id.gid ); pstrcpy( suffix, lp_ldap_group_suffix() ); } + + DEBUG(5,("ldap_get_sid_from_id: Searching \"%s\"\n", filter )); attr_list = get_attr_list( sidmap_attr_list ); - snprintf(filter, sizeof(filter), "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))", + pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))", LDAP_OBJ_IDMAP_ENTRY, obj_class, type, id_str); rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result); - if (rc != LDAP_SUCCESS) + if (rc != LDAP_SUCCESS) { + DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n", + ldap_err2string(rc) )); goto out; - + } + count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); + + if (count > 1) { + DEBUG(0,("ldap_get_sid_from_id: mapping returned [%d] entries!\n", + count)); + goto out; + } /* fall back to looking up an idmap entry if we didn't find and actual user or group */ @@ -487,24 +481,30 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) ldap_msgfree(result); result = NULL; - snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))", - LDAP_OBJ_IDMAP_ENTRY, type, ((id_type & ID_USERID) ? id.uid : id.gid)); + pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))", + LDAP_OBJ_IDMAP_ENTRY, type, + ((id_type & ID_USERID) ? (unsigned long)id.uid : + (unsigned long)id.gid)); pstrcpy( suffix, lp_ldap_idmap_suffix() ); rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result); - if (rc != LDAP_SUCCESS) - goto out; + if (rc != LDAP_SUCCESS) { + DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n", + ldap_err2string(rc) )); + goto out; + } count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); - } - - if (count != 1) { - 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; + + if (count != 1) { + DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n", + type, ((id_type & ID_USERID) ? (unsigned long)id.uid : + (unsigned long)id.gid))); + goto out; + } } entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); @@ -538,117 +538,146 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si pstring id_str; const char *suffix; const char *type; - const char *obj_class; - const char *posix_obj_class; int rc; int count; char **attr_list; char *dn = NULL; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - /* first try getting the mapping from a samba user or group */ - sid_to_string(sid_str, sid); - if ( *id_type & ID_USERID ) { - type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ); - obj_class = LDAP_OBJ_SAMBASAMACCOUNT; - posix_obj_class = LDAP_OBJ_POSIXACCOUNT; - suffix = lp_ldap_suffix(); - snprintf(filter, sizeof(filter), - "(&(|(&(objectClass=%s)(objectClass=%s))(objectClass=%s))(%s=%s))", - obj_class, posix_obj_class, LDAP_OBJ_IDMAP_ENTRY, - get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ), - sid_str); - } - else { + + DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str, + (*id_type & ID_GROUPID ? "group" : "user") )); + + /* ahhh.... ok. We have to check users and groups in places other + than idmap (hint: we're a domain member of a Samba domain) */ + + if ( *id_type & ID_GROUPID ) { + type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ); - obj_class = LDAP_OBJ_GROUPMAP; - posix_obj_class = LDAP_OBJ_POSIXGROUP; suffix = lp_ldap_group_suffix(); - snprintf(filter, sizeof(filter), - "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))", - obj_class, LDAP_OBJ_IDMAP_ENTRY, + pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))", + LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY, + get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ), + sid_str); + + } + else { + + type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ); + suffix = lp_ldap_suffix(); + pstr_sprintf(filter, "(&(|(&(objectClass=%s)(objectClass=%s))(objectClass=%s))(%s=%s))", + LDAP_OBJ_SAMBASAMACCOUNT, LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_IDMAP_ENTRY, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ), sid_str); + } - + + DEBUG(10,("ldap_get_id_from_sid: Searching for \"%s\"\n", filter)); + + /* do the search and check for errors */ + attr_list = get_attr_list( sidmap_attr_list ); rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, - filter, attr_list, 0, &result); - - if (rc != LDAP_SUCCESS) + filter, attr_list, 0, &result); + + if ( rc != LDAP_SUCCESS ) { + DEBUG(3,("ldap_get_id_from_sid: Failure looking up group mapping (%s)\n", + ldap_err2string(rc) )); goto out; + } count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); - - /* fall back to looking up an idmap entry if we didn't find anything under the idmap - user or group suffix */ - if (count == 0) { - ldap_msgfree(result); - - snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%s))", - LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str); + if ( count > 1 ) { + DEBUG(3,("ldap_get_id_from_sid: search \"%s\" returned [%d] entries. Bailing...\n", + filter, count)); + goto out; + } + + /* see if we need to do a search here */ + + if ( count == 0 ) { + + if ( result ) { + ldap_msgfree(result); + result = NULL; + } + + /* look in idmap suffix */ suffix = lp_ldap_idmap_suffix(); + pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", + LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str); rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result); - if (rc != LDAP_SUCCESS) + if (rc != LDAP_SUCCESS) { + DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n", + ldap_err2string(rc) )); goto out; + } + /* check for the number of entries returned */ + count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); - } - if ( count > 1 ) { - DEBUG(0, ("ldap_get_id_from_sid: search %s returned more than on entry!\n", - filter)); - goto out; - } - - /* we might have an existing entry to work with so pull out the requested information */ - - if ( count ) { - entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); - - dn = ldap_get_dn(ldap_state.smbldap_state->ldap_struct, result); - DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn, type)); - - if ( smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, type, id_str) ) - { - if ( (*id_type & ID_USERID) ) - id->uid = strtoul(id_str, NULL, 10); - else - id->gid = strtoul(id_str, NULL, 10); - - ret = NT_STATUS_OK; + if ( count > 1 ) { + DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n", + filter, count)); goto out; } - } - if (!(*id_type & ID_QUERY_ONLY)) { - /* if entry == NULL, and we are asked to - allocate a new id */ - int i; + + /* try to allocate a new id if we still haven't found one */ + + if ( (count==0) && !(*id_type & ID_QUERY_ONLY) ) { + int i; + + DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n")); - for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) - { - ret = ldap_allocate_id(id, *id_type); - if ( NT_STATUS_IS_OK(ret) ) - break; - } + 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) ) { - DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n")); + if ( !NT_STATUS_IS_OK(ret) ) { + DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n")); + goto out; + } + + DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n", + (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid )); + + ret = ldap_set_mapping(sid, *id, *id_type); + + /* all done */ + goto out; } - - ret = ldap_set_mapping(sid, *id, *id_type); - } else { - /* no match, and not adding one */ - ret = NT_STATUS_UNSUCCESSFUL; } + DEBUG(10,("ldap_get_id_from_sid: success\n")); + + entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); + + dn = ldap_get_dn(ldap_state.smbldap_state->ldap_struct, result); + + DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn, type)); + + if ( smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, type, id_str) ) + { + if ( (*id_type & ID_USERID) ) + id->uid = strtoul(id_str, NULL, 10); + else + id->gid = strtoul(id_str, NULL, 10); + + ret = NT_STATUS_OK; + goto out; + } + out: free_attr_list( attr_list ); if (result) @@ -670,7 +699,7 @@ static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id, int id_type, const char *ldap_dn, LDAPMessage *entry) { - char *dn = NULL; + pstring dn; pstring id_str; fstring type; LDAPMod **mods = NULL; @@ -685,24 +714,20 @@ static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id, if (ldap_dn) { DEBUG(10, ("Adding new IDMAP mapping on DN: %s", ldap_dn)); ldap_op = LDAP_MOD_REPLACE; - dn = strdup(ldap_dn); + pstrcpy( dn, ldap_dn ); } else { ldap_op = LDAP_MOD_ADD; - asprintf(&dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID), + pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID), sid_string, lp_ldap_idmap_suffix()); } - if (!dn) { - DEBUG(0, ("ldap_set_mapping_internals: out of memory allocating DN!\n")); - return NT_STATUS_NO_MEMORY; - } - if ( id_type & ID_USERID ) fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ) ); else fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ) ); - snprintf(id_str, sizeof(id_str), "%u", ((id_type & ID_USERID) ? id.uid : id.gid)); + pstr_sprintf(id_str, "%lu", ((id_type & ID_USERID) ? (unsigned long)id.uid : + (unsigned long)id.gid)); if (entry) values = ldap_get_values(ldap_state.smbldap_state->ldap_struct, entry, "objectClass"); @@ -754,15 +779,16 @@ static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id, char *ld_error = NULL; ldap_get_option(ldap_state.smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); - DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %u [%s]\n", + DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n", (ldap_op == LDAP_MOD_ADD) ? "add" : "replace", - sid_string, (unsigned int)((id_type & ID_USERID) ? id.uid : id.gid), type)); + sid_string, (unsigned long)((id_type & ID_USERID) ? id.uid : id.gid), type)); DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n", ld_error ? ld_error : "(NULL)", ldap_err2string (rc))); return NT_STATUS_UNSUCCESSFUL; } - DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %d [%s]\n", - sid_string, ((id_type & ID_USERID) ? id.uid : id.gid), type)); + DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n", + sid_string, ((id_type & ID_USERID) ? (unsigned long)id.uid : + (unsigned long)id.gid), type)); return NT_STATUS_OK; } @@ -794,18 +820,18 @@ static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) suffix = lp_ldap_suffix(); type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ); posix_obj_class = LDAP_OBJ_POSIXACCOUNT; - snprintf(id_str, sizeof(id_str), "%u", id.uid ); + fstr_sprintf(id_str, "%lu", (unsigned long)id.uid ); } else { obj_class = LDAP_OBJ_GROUPMAP; suffix = lp_ldap_group_suffix(); type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); posix_obj_class = LDAP_OBJ_POSIXGROUP; - snprintf(id_str, sizeof(id_str), "%u", id.gid ); + fstr_sprintf(id_str, "%lu", (unsigned long)id.gid ); } sid_to_string(sid_str, sid); - snprintf(filter, sizeof(filter), + pstr_sprintf(filter, "(|" "(&(|(objectClass=%s)(|(objectClass=%s)(objectClass=%s)))(%s=%s))" "(&(objectClass=%s)(%s=%s))" @@ -859,10 +885,13 @@ out: return ret; } -/***************************************************************************** - Initialise idmap database. -*****************************************************************************/ -static NTSTATUS ldap_idmap_init( char *params ) + + +/********************************************************************** + Verify the sambaUnixIdPool entry in the directiry. +**********************************************************************/ + +static NTSTATUS verify_idpool( void ) { fstring filter; int rc; @@ -870,24 +899,8 @@ static NTSTATUS ldap_idmap_init( char *params ) LDAPMessage *result = NULL; LDAPMod **mods = NULL; int count; - NTSTATUS nt_status; - - ldap_state.mem_ctx = talloc_init("idmap_ldap"); - if (!ldap_state.mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - /* assume location is the only parameter */ - if (!NT_STATUS_IS_OK(nt_status = - smbldap_init(ldap_state.mem_ctx, params, - &ldap_state.smbldap_state))) { - talloc_destroy(ldap_state.mem_ctx); - return nt_status; - } - - /* see if the idmap suffix and sub entries exists */ - snprintf( filter, sizeof(filter), "(objectclass=%s)", LDAP_OBJ_IDPOOL ); + fstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_IDPOOL ); attr_list = get_attr_list( idpool_attr_list ); rc = smbldap_search(ldap_state.smbldap_state, lp_ldap_idmap_suffix(), @@ -914,8 +927,8 @@ static NTSTATUS ldap_idmap_init( char *params ) return NT_STATUS_UNSUCCESSFUL; } - snprintf( uid_str, sizeof(uid_str), "%d", luid ); - snprintf( gid_str, sizeof(gid_str), "%d", lgid ); + fstr_sprintf( uid_str, "%lu", (unsigned long)luid ); + fstr_sprintf( gid_str, "%lu", (unsigned long)lgid ); smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDPOOL ); smbldap_set_mod( &mods, LDAP_MOD_ADD, @@ -925,7 +938,36 @@ static NTSTATUS ldap_idmap_init( char *params ) rc = smbldap_modify(ldap_state.smbldap_state, lp_ldap_idmap_suffix(), mods); } + + return ( rc==LDAP_SUCCESS ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); +} + +/***************************************************************************** + Initialise idmap database. +*****************************************************************************/ +static NTSTATUS ldap_idmap_init( char *params ) +{ + NTSTATUS nt_status; + + ldap_state.mem_ctx = talloc_init("idmap_ldap"); + if (!ldap_state.mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + /* assume location is the only parameter */ + if (!NT_STATUS_IS_OK(nt_status = + smbldap_init(ldap_state.mem_ctx, params, + &ldap_state.smbldap_state))) { + talloc_destroy(ldap_state.mem_ctx); + return nt_status; + } + + /* see if the idmap suffix and sub entries exists */ + nt_status = verify_idpool(); + if ( !NT_STATUS_IS_OK(nt_status) ) + return nt_status; + return NT_STATUS_OK; } |