-/***********************************************************************
- This function cannot be called to modify a mapping, only set a new one
-
- This takes a possible pointer to the existing entry for the UID or SID
- involved.
-***********************************************************************/
-
-static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id,
- int id_type, const char *ldap_dn,
- LDAPMessage *entry)
-{
- pstring dn;
- pstring id_str;
- fstring type;
- LDAPMod **mods = NULL;
- int rc = -1;
- int ldap_op;
- fstring sid_string;
- char **values = NULL;
- int i;
-
- sid_to_string( sid_string, sid );
-
- if (ldap_dn) {
- DEBUG(10, ("Adding new IDMAP mapping on DN: %s", ldap_dn));
- ldap_op = LDAP_MOD_REPLACE;
- pstrcpy( dn, ldap_dn );
- } else {
- ldap_op = LDAP_MOD_ADD;
- pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID),
- sid_string, lp_ldap_idmap_suffix());
- }
-
- 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 ) );
-
- 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");
-
- if (values) {
- BOOL found_idmap = False;
- for (i=0; values[i]; i++) {
- if (StrCaseCmp(values[i], LDAP_OBJ_IDMAP_ENTRY) == 0) {
- found_idmap = True;
- break;
- }
- }
- if (!found_idmap)
- smbldap_set_mod( &mods, LDAP_MOD_ADD,
- "objectClass", LDAP_OBJ_IDMAP_ENTRY );
- } else {
- smbldap_set_mod( &mods, LDAP_MOD_ADD,
- "objectClass", LDAP_OBJ_IDMAP_ENTRY );
- }
-
- smbldap_make_mod( ldap_state.smbldap_state->ldap_struct,
- entry, &mods, type, id_str );
-
- smbldap_make_mod( ldap_state.smbldap_state->ldap_struct,
- entry, &mods,
- get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
- sid_string );
-
- /* There may well be nothing at all to do */
- if (mods) {
- switch(ldap_op)
- {
- case LDAP_MOD_ADD:
- smbldap_set_mod( &mods, LDAP_MOD_ADD,
- "objectClass", LDAP_OBJ_SID_ENTRY );
- rc = smbldap_add(ldap_state.smbldap_state, dn, mods);
- break;
- case LDAP_MOD_REPLACE:
- rc = smbldap_modify(ldap_state.smbldap_state, dn, mods);
- break;
- }
-
- ldap_mods_free( mods, True );
- } else {
- rc = LDAP_SUCCESS;
- }
-
- if (rc != LDAP_SUCCESS) {
- 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 %lu [%s]\n",
- (ldap_op == LDAP_MOD_ADD) ? "add" : "replace",
- 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 %lu [%s]\n",
- sid_string, ((id_type & ID_USERID) ? (unsigned long)id.uid :
- (unsigned long)id.gid), type));
-
- return NT_STATUS_OK;
-}
-
-/***********************************************************************
- 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)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- char *dn = NULL;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- const char *type;
- const char *obj_class;
- const char *posix_obj_class;
- const char *suffix;
- fstring sid_str;
- fstring id_str;
- pstring filter;
- char **attr_list;
- int rc;
- int count;
-
- /* try for a samba user or group mapping (looking for an entry with a SID) */
- if ( id_type & ID_USERID ) {
- obj_class = LDAP_OBJ_SAMBASAMACCOUNT;
- suffix = lp_ldap_suffix();
- type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER );
- posix_obj_class = LDAP_OBJ_POSIXACCOUNT;
- 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;
- fstr_sprintf(id_str, "%lu", (unsigned long)id.gid );
- }
-
- sid_to_string(sid_str, sid);
- pstr_sprintf(filter,
- "(|"
- "(&(|(objectClass=%s)(|(objectClass=%s)(objectClass=%s)))(%s=%s))"
- "(&(objectClass=%s)(%s=%s))"
- ")",
- /* objectClasses that might contain a SID */
- LDAP_OBJ_SID_ENTRY, LDAP_OBJ_IDMAP_ENTRY, obj_class,
- get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ),
- sid_str,
-
- /* objectClasses that might contain a Unix UID/GID */
- posix_obj_class,
- /* Unix UID/GID specifier*/
- type,
- /* actual ID */
- id_str);
-
- attr_list = get_attr_list( sidmap_attr_list );
- rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
- free_attr_list( attr_list );
-
- if (rc != LDAP_SUCCESS)
- 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 == 1) {
- entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
-
- dn = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, result);
- if (!dn)
- goto out;
- DEBUG(10, ("Found partial mapping entry at dn=%s, looking for %s\n", dn, type));
-
- ret = ldap_set_mapping_internals(sid, id, id_type, dn, entry);
-
- goto out;
- } else if (count > 1) {
- DEBUG(0, ("Too many entries trying to find DN to attach ldap \n"));
- goto out;
- }
-
- ret = ldap_set_mapping_internals(sid, id, id_type, NULL, NULL);
-
-out:
- if (result)
- ldap_msgfree(result);
- SAFE_FREE(dn);
-
- return ret;
-}
-
-