summaryrefslogtreecommitdiff
path: root/source4/auth/sam.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-06-04 14:07:35 +1000
committerAndrew Tridgell <tridge@samba.org>2009-06-04 14:10:11 +1000
commitdfd56dd29415b06b5ea137f8c333da42e8ff1aa6 (patch)
tree487d0e8f42b6f2c39b15fcea4a1ae52b60518a6b /source4/auth/sam.c
parent0849c1ef77a0538d5d232016a51c002e2197e776 (diff)
downloadsamba-dfd56dd29415b06b5ea137f8c333da42e8ff1aa6.tar.gz
samba-dfd56dd29415b06b5ea137f8c333da42e8ff1aa6.tar.bz2
samba-dfd56dd29415b06b5ea137f8c333da42e8ff1aa6.zip
changed the auth path to use extended DN ops to avoid non-indexed searches
Logs showed that every SAM authentication was causing a non-indexed ldb search for member=XXX. This was previously indexed in Samba4, but since we switched to using the indexes from the full AD schema it now isn't. The fix is to use the extended DN operations to allow us to ask the server for the memberOf attribute instead, with with the SIDs attached to the result. This also means one less search on every authentication. The patch is made more complex by the fact that some common routines use the result of these user searches, so we had to update all searches that uses user_attrs and those common routines to make sure they all returned a ldb_message with a memberOf filled in and the SIDs attached.
Diffstat (limited to 'source4/auth/sam.c')
-rw-r--r--source4/auth/sam.c84
1 files changed, 47 insertions, 37 deletions
diff --git a/source4/auth/sam.c b/source4/auth/sam.c
index c70c02cb3c..68eaacf255 100644
--- a/source4/auth/sam.c
+++ b/source4/auth/sam.c
@@ -28,6 +28,7 @@
#include "libcli/security/security.h"
#include "libcli/ldap/ldap.h"
#include "librpc/gen_ndr/ndr_netlogon.h"
+#include "librpc/gen_ndr/ndr_security.h"
#include "param/param.h"
#include "auth/auth_sam.h"
@@ -66,6 +67,7 @@ const char *user_attrs[] = {
"badPwdCount",
"logonCount",
"primaryGroupID",
+ "memberOf",
NULL,
};
@@ -261,9 +263,7 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
struct auth_serversupplied_info **_server_info)
{
struct auth_serversupplied_info *server_info;
- struct ldb_message **group_msgs;
- int group_ret;
- const char *group_attrs[3] = { "sAMAccountType", "objectSid", NULL };
+ int group_ret = 0;
/* find list of sids */
struct dom_sid **groupSIDs = NULL;
struct dom_sid *account_sid;
@@ -271,39 +271,48 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
const char *str;
int i;
uint_t rid;
- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-
- group_ret = gendb_search(sam_ctx,
- tmp_ctx, NULL, &group_msgs, group_attrs,
- "(&(member=%s)(sAMAccountType=*))",
- ldb_dn_get_linearized(msg->dn));
- if (group_ret == -1) {
- talloc_free(tmp_ctx);
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ struct ldb_message_element *el;
- server_info = talloc(mem_ctx, struct auth_serversupplied_info);
- NT_STATUS_HAVE_NO_MEMORY(server_info);
+ server_info = talloc(tmp_ctx, struct auth_serversupplied_info);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info, tmp_ctx);
- if (group_ret > 0) {
+ el = ldb_msg_find_element(msg, "memberOf");
+ if (el != NULL) {
+ group_ret = el->num_values;
groupSIDs = talloc_array(server_info, struct dom_sid *, group_ret);
- NT_STATUS_HAVE_NO_MEMORY(groupSIDs);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupSIDs, tmp_ctx);
}
- /* Need to unroll some nested groups, but not aliases */
+ /* TODO Note: this is incomplete. We need to unroll some
+ * nested groups, but not aliases */
for (i = 0; i < group_ret; i++) {
- groupSIDs[i] = samdb_result_dom_sid(groupSIDs,
- group_msgs[i], "objectSid");
- NT_STATUS_HAVE_NO_MEMORY(groupSIDs[i]);
+ struct ldb_dn *dn;
+ const struct ldb_val *v;
+ enum ndr_err_code ndr_err;
+
+ dn = ldb_dn_from_ldb_val(tmp_ctx, sam_ctx, &el->values[i]);
+ if (dn == NULL) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ v = ldb_dn_get_extended_component(dn, "SID");
+ groupSIDs[i] = talloc(groupSIDs, struct dom_sid);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupSIDs[i], tmp_ctx);
+
+ ndr_err = ndr_pull_struct_blob(v, groupSIDs[i], NULL, groupSIDs[i],
+ (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
}
- talloc_free(tmp_ctx);
-
account_sid = samdb_result_dom_sid(server_info, msg, "objectSid");
- NT_STATUS_HAVE_NO_MEMORY(account_sid);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid, tmp_ctx);
primary_group_sid = dom_sid_dup(server_info, account_sid);
- NT_STATUS_HAVE_NO_MEMORY(primary_group_sid);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_sid, tmp_ctx);
rid = samdb_result_uint(msg, "primaryGroupID", ~0);
if (rid == ~0) {
@@ -325,30 +334,30 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
server_info->account_name = talloc_steal(server_info, samdb_result_string(msg, "sAMAccountName", NULL));
server_info->domain_name = talloc_strdup(server_info, domain_name);
- NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->domain_name, tmp_ctx);
str = samdb_result_string(msg, "displayName", "");
server_info->full_name = talloc_strdup(server_info, str);
- NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->full_name, tmp_ctx);
str = samdb_result_string(msg, "scriptPath", "");
server_info->logon_script = talloc_strdup(server_info, str);
- NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->logon_script, tmp_ctx);
str = samdb_result_string(msg, "profilePath", "");
server_info->profile_path = talloc_strdup(server_info, str);
- NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->profile_path, tmp_ctx);
str = samdb_result_string(msg, "homeDirectory", "");
server_info->home_directory = talloc_strdup(server_info, str);
- NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->home_directory, tmp_ctx);
str = samdb_result_string(msg, "homeDrive", "");
server_info->home_drive = talloc_strdup(server_info, str);
- NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->home_drive, tmp_ctx);
server_info->logon_server = talloc_strdup(server_info, netbios_name);
- NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->logon_server, tmp_ctx);
server_info->last_logon = samdb_result_nttime(msg, "lastLogon", 0);
server_info->last_logoff = samdb_result_nttime(msg, "lastLogoff", 0);
@@ -373,7 +382,7 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
server_info->authenticated = true;
- *_server_info = server_info;
+ *_server_info = talloc_steal(mem_ctx, server_info);
return NT_STATUS_OK;
}
@@ -381,7 +390,7 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx,
TALLOC_CTX *mem_ctx, const char *principal,
struct ldb_dn **domain_dn,
- struct ldb_message ***msgs)
+ struct ldb_message **msg)
{
struct ldb_dn *user_dn;
NTSTATUS nt_status;
@@ -399,12 +408,13 @@ NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx,
}
/* pull the user attributes */
- ret = gendb_search_dn(sam_ctx, tmp_ctx, user_dn, msgs, user_attrs);
- if (ret != 1) {
+ ret = gendb_search_single_extended_dn(sam_ctx, tmp_ctx, user_dn, LDB_SCOPE_BASE,
+ msg, user_attrs, "(objectClass=*)");
+ if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- talloc_steal(mem_ctx, *msgs);
+ talloc_steal(mem_ctx, *msg);
talloc_steal(mem_ctx, *domain_dn);
talloc_free(tmp_ctx);