diff options
author | Simo Sorce <idra@samba.org> | 2004-03-19 14:31:09 +0000 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2004-03-19 14:31:09 +0000 |
commit | c8549363f49ac9ea818bd782319e57154764992f (patch) | |
tree | d1bfa900298151662dd669288860624e0998d2fe /source3/passdb | |
parent | 9915ded60a1c59528ab6485dc14ac34f19f6153f (diff) | |
download | samba-c8549363f49ac9ea818bd782319e57154764992f.tar.gz samba-c8549363f49ac9ea818bd782319e57154764992f.tar.bz2 samba-c8549363f49ac9ea818bd782319e57154764992f.zip |
add privileges support to ldapsam too
(This used to be commit d940a2f77377dd1560cea4c782823cf9cd97a3aa)
Diffstat (limited to 'source3/passdb')
-rw-r--r-- | source3/passdb/pdb_ldap.c | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 2141f2a3f1..da5bfbecbb 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -2330,6 +2330,318 @@ static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods, } /********************************************************************** + Privileges related functions + *********************************************************************/ + +static NTSTATUS ldapsam_modify_sid_list_for_privilege(struct pdb_methods *my_methods, const char *privname, const DOM_SID *sid, int ldap_op) +{ + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + LDAPMessage *entry = NULL; + LDAPMod **mods = NULL; + fstring sid_str; + fstring filter; + char **attr_list, *dn; + int rc, i; + + if ((sid == NULL) || (!sid_to_string(sid_str, sid))) { + DEBUG(3, ("ldapsam_modify_sid_list_for_privilege: Invalid SID\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + pstr_sprintf(filter, "(&(objectclass=%s)(sambaPrivName=%s))", LDAP_OBJ_PRIVILEGE, privname); + attr_list = get_attr_list(privilege_attr_list); + rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_privilege_suffix(), + LDAP_SCOPE_SUBTREE, filter, + attr_list, 0, &ldap_state->result); + free_attr_list(attr_list); + + + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ldapsam_modify_sid_list_for_privilege: LDAP search failed: %s\n", ldap_err2string(rc))); + DEBUG(3, ("ldapsam_modify_sid_list_for_privilege: Query was: %s, %s\n", lp_ldap_privilege_suffix(), filter)); + ldap_msgfree(ldap_state->result); + ldap_state->result = NULL; + goto done; + } + + if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 0) { + /* if the privilege does not exist and we are adding then + * create it */ + if (ldap_op == LDAP_MOD_ADD) { + + DEBUG(3, ("Privilege not found on ldap tree, creating a new entry\n")); + if (asprintf(&dn, "sambaPrivName=%s,%s", privname, lp_ldap_privilege_suffix()) < 0) { + DEBUG(0, ("ldapsam_modify_sid_list_for_privilege: Out of memory\n")); + goto done; + } + + smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaPrivName", privname); + + smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_PRIVILEGE); + + rc = smbldap_add(ldap_state->smbldap_state, dn, mods); + + if (rc != LDAP_SUCCESS) { + char *ld_error = NULL; + + ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); + DEBUG(1, + ("ldapsam_modify_sid_list_for_privilege:" + "Failed to add privilege (%s) dn= %s with: %s\n\t%s\n", + privname, + dn, ldap_err2string(rc), + ld_error ? ld_error : "unknown") + ); + + SAFE_FREE(ld_error); + goto done; + } + + pstr_sprintf(filter, "(&(objectclass=%s)(sambaPrivName=%s))", LDAP_OBJ_PRIVILEGE, privname); + attr_list = get_attr_list(privilege_attr_list); + rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_privilege_suffix(), + LDAP_SCOPE_SUBTREE, filter, + attr_list, 0, &ldap_state->result); + free_attr_list(attr_list); + + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ldapsam_modify_sid_list_for_privilege: LDAP search failed: %s\n", ldap_err2string(rc))); + DEBUG(3, ("ldapsam_modify_sid_list_for_privilege: Query was: %s, %s\n", lp_ldap_privilege_suffix(), filter)); + ldap_msgfree(ldap_state->result); + ldap_state->result = NULL; + goto done; + } + } else { + goto done; + } + } + /* entry found */ + entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result); + + /* retrieve the dn */ + dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry); + if (!dn) { + goto done; + } + + /* prepare the modification */ + smbldap_set_mod(&mods, ldap_op, "sambaSIDList", sid_str); + + /* modify the privilege */ + rc = smbldap_modify(ldap_state->smbldap_state, dn, mods); + + /* free used structures */ + ldap_mods_free(mods, True); + + if (rc != LDAP_SUCCESS) { + char *ld_error = NULL; + + ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); + DEBUG(1, + ("ldapsam_modify_sid_list_for_privilege:" + "Failed to %s sid for privilege (%s) dn= %s with: %s\n\t%s\n", + (ldap_op == LDAP_MOD_ADD) ? "add" : "remove", + privname, + dn, ldap_err2string(rc), + ld_error ? ld_error : "unknown") + ); + SAFE_FREE(ld_error); + goto done; + } + + ret = NT_STATUS_OK; + +done: + return ret; +} + +static NTSTATUS ldapsam_add_sid_to_privilege(struct pdb_methods *my_methods, const char *privname, const DOM_SID *sid) +{ + return ldapsam_modify_sid_list_for_privilege(my_methods, privname, sid, LDAP_MOD_ADD); +} + +static NTSTATUS ldapsam_remove_sid_from_privilege(struct pdb_methods *my_methods, const char *privname, const DOM_SID *sid) +{ + return ldapsam_modify_sid_list_for_privilege(my_methods, privname, sid, LDAP_MOD_DELETE); +} + +static NTSTATUS ldapsam_get_privilege_set(struct pdb_methods *my_methods, NT_USER_TOKEN *token, PRIVILEGE_SET *privset) +{ + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + LDAPMessage *entry = NULL; + fstring sid_str; + fstring filter; + char **sid_list; + char **attr_list; + int rc, i; + + sid_list = (char **)malloc(sizeof(char *) * (token->num_sids + 1)); + for (i = 0; i < token->num_sids; i++) { + sid_to_string(sid_str, &token->user_sids[i]); + sid_list[i] = strdup(sid_str); + if ( ! sid_list[i]) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } + } + sid_list[i] = NULL; + + pstr_sprintf(filter, "(objectclass=%s)", LDAP_OBJ_PRIVILEGE); + attr_list = get_attr_list(privilege_attr_list); + rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_privilege_suffix(), + LDAP_SCOPE_SUBTREE, filter, + attr_list, 0, &ldap_state->result); + free_attr_list(attr_list); + + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ldapsam_get_privilege_set: LDAP search failed: %s\n", ldap_err2string(rc))); + DEBUG(3, ("ldapsam_get_privilege_set: Query was: %s, %s\n", lp_ldap_privilege_suffix(), filter)); + ldap_msgfree(ldap_state->result); + ldap_state->result = NULL; + goto done; + } + + if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 0) { + DEBUG(3, ("ldapsam_get_privilege_set: No privileges in ldap tree\n")); + ret = NT_STATUS_OK; + goto done; + } + + DEBUG(2, ("ldapsam_get_privilege_set: %d entries in the base!\n", + ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result))); + + entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result); + + while (entry != NULL) { + char **values = NULL; + + for(i=0; sid_list[i] != NULL; i++) { + char *c, *s; + pstring privname; + int j; + + if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, "sambaPrivName", privname, sizeof(pstring))) { + goto loop; + } + + if ((values = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID_LIST)) == NULL) { + DEBUG(10, ("ldapsam_get_privilege_set: SID List not found skipping privilege\n")); + goto loop; + } + + j = 0; + while (values[j] != 0) { + if (strcmp(values[j], sid_list[i]) == 0) { + DEBUG(10, ("sid [%s] found in users sid list\n", sid_list[i])); + DEBUG(10, ("adding privilege [%s] to the users privilege list\n", privname)); + add_privilege_by_name(privset, privname); + goto loop; + } + j++; + } + + if (values) { + ldap_value_free(values); + values = NULL; + } + } + loop: + if (values) { + ldap_value_free(values); + } + + entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct, entry); + } + + ret = NT_STATUS_OK; + +done: + i = 0; + while (sid_list[i]) { + free(sid_list[i]); + i++; + } + free(sid_list); + + return ret; +} + +static NTSTATUS ldapsam_get_privilege_entry(struct pdb_methods *my_methods, const char *privname, + char **sid_list) +{ + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + LDAPMessage *entry = NULL; + fstring sid_str; + fstring filter; + char **attr_list, **values; + int rc, i, len; + + *sid_list = NULL; + pstr_sprintf(filter, "(&(objectclass=%s)(sambaPrivName=%s))", LDAP_OBJ_PRIVILEGE, privname); + attr_list = get_attr_list(privilege_attr_list); + rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_privilege_suffix(), + LDAP_SCOPE_SUBTREE, filter, + attr_list, 0, &ldap_state->result); + free_attr_list(attr_list); + + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ldapsam_get_privilege_entry: LDAP search failed: %s\n", ldap_err2string(rc))); + DEBUG(3, ("ldapsam_get_privilege_entry: Query was: %s, %s\n", lp_ldap_privilege_suffix(), filter)); + ldap_msgfree(ldap_state->result); + ldap_state->result = NULL; + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 0) { + DEBUG(3, ("ldapsam_get_privilege_entry: No such privilege (%s) in ldap tree\n", privname)); + goto done; + } + + entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result); + + if ((values = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID_LIST)) == NULL) { + DEBUG(10, ("ldapsam_get_privilege_entry: SID List not found skipping privilege\n")); + ret = NT_STATUS_OK; + goto done; + } + + for (i = 0, len = 0; values[i] != 0; i++ ) { + len = len + strlen(values[i]) + 1; + } + + *sid_list = (char *)malloc(len); + if ((*sid_list) == NULL) { + DEBUG(0, ("ldapsam_get_privilege_entry: Out of memory!\n")); + ldap_value_free(values); + ret = NT_STATUS_NO_MEMORY; + goto done; + } + + (*sid_list)[0] = '\0'; + + for (i = 0; values[i] != 0; i++ ) { + if (i != 0) { + strlcat(*sid_list, ",", len); + } + DEBUG(0, ("sid_list = [%s]\n", *sid_list)); + DEBUG(0, ("values = [%s]\n", values[i])); + DEBUG(0, ("len = [%d]\n", len)); + strlcat(*sid_list, values[i], len); + DEBUG(0, ("sid_list = [%s]\n", *sid_list)); + } + + ldap_value_free(values); + ret = NT_STATUS_OK; +done: + return ret; +} + + +/********************************************************************** Housekeeping *********************************************************************/ @@ -2382,6 +2694,11 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS ** (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry; (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping; + (*pdb_method)->add_sid_to_privilege = ldapsam_add_sid_to_privilege; + (*pdb_method)->remove_sid_from_privilege = ldapsam_remove_sid_from_privilege; + (*pdb_method)->get_privilege_set = ldapsam_get_privilege_set; + (*pdb_method)->get_privilege_entry = ldapsam_get_privilege_entry; + /* TODO: Setup private data and free */ ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(*ldap_state)); |