1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-27 14:04:05 +03:00

Added negative caching to group lookups.

Jeremy.
This commit is contained in:
Jeremy Allison -
parent 17e2f38973
commit fceba7dea5
2 changed files with 87 additions and 48 deletions

View File

@ -1,10 +1,11 @@
/*
Unix SMB/Netbios implementation.
Version 2.0
Version 2.2.
Winbind daemon for ntdom nss module
Copyright (C) Tim Potter 2000
Copyright (C) Jeremy Allison 2001.
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
@ -23,6 +24,12 @@
#include "winbindd.h"
/***************************************************************
Empty static struct for negative caching.
****************************************************************/
static struct winbindd_gr negative_gr_cache_entry;
/* Fill a grent structure from various other information */
static BOOL fill_grent(struct winbindd_gr *gr, char *gr_name,
@ -174,6 +181,7 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
result = True;
done:
talloc_destroy(mem_ctx);
DEBUG(10, ("fill_grent_mem(): returning %d\n", result));
@ -183,8 +191,7 @@ done:
/* Return a group structure from a group name */
enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
*state)
enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state *state)
{
DOM_SID group_sid;
struct winbindd_domain *domain;
@ -225,6 +232,13 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
&state->response.data.gr,
&state->response.extra_data,
&extra_data_len)) {
/* Check if this is a negative cache entry. */
if (memcmp(&negative_gr_cache_entry, &state->response.data.gr,
sizeof(state->response.data.gr)) == 0)
return WINBINDD_ERROR;
state->response.length += extra_data_len;
return WINBINDD_OK;
}
@ -236,12 +250,20 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
if (!winbindd_lookup_sid_by_name(name, &group_sid, &name_type)) {
DEBUG(1, ("group %s in domain %s does not exist\n",
name_group, name_domain));
winbindd_store_group_cache_entry(domain, name_group,
&negative_gr_cache_entry, NULL, 0);
return WINBINDD_ERROR;
}
if ((name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_DOM_GRP)) {
DEBUG(1, ("from_group: name '%s' is not a local or domain "
"group: %d\n", name_group, name_type));
winbindd_store_group_cache_entry(domain, name_group,
&negative_gr_cache_entry, NULL, 0);
return WINBINDD_ERROR;
}
@ -251,6 +273,10 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
if (!winbindd_idmap_get_gid_from_rid(domain->name, group_rid, &gid)) {
DEBUG(1, ("error sursing unix gid for sid\n"));
winbindd_store_group_cache_entry(domain, name_group,
&negative_gr_cache_entry, NULL, 0);
return WINBINDD_ERROR;
}
@ -258,8 +284,13 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
state->request.data.groupname, gid) ||
!fill_grent_mem(domain, group_rid, name_type,
&state->response.data.gr.num_gr_mem,
&gr_mem, &gr_mem_len))
&gr_mem, &gr_mem_len)) {
winbindd_store_group_cache_entry(domain, name_group,
&negative_gr_cache_entry, NULL, 0);
return WINBINDD_ERROR;
}
/* Group membership lives at start of extra data */
@ -316,6 +347,13 @@ enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_cli_state
&state->response.data.gr,
&state->response.extra_data,
&extra_data_len)) {
/* Check if this is a negative cache entry. */
if (memcmp(&negative_gr_cache_entry, &state->response.data.gr,
sizeof(state->response.data.gr)) == 0)
return WINBINDD_ERROR;
state->response.length += extra_data_len;
return WINBINDD_OK;
}
@ -483,8 +521,7 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
break;
status = cli_samr_open_domain(hnd->cli, mem_ctx,
&hnd->pol, des_access,
&ent->domain->sid, &dom_pol);
&hnd->pol, des_access, &ent->domain->sid, &dom_pol);
if (!NT_STATUS_IS_OK(status))
break;
@ -544,6 +581,7 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
result = (ent->num_sam_entries > 0);
done:
talloc_destroy(mem_ctx);
return result;
@ -748,6 +786,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
/* Out of domains */
done:
return (group_list_ndx > 0) ? WINBINDD_OK : WINBINDD_ERROR;
}
@ -950,9 +989,8 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
num_gids = 0;
gid_list = malloc(sizeof(gid_t) * num_groups);
if (state->response.extra_data) {
if (state->response.extra_data)
goto done;
}
for (i = 0; i < num_groups; i++) {
if (!winbindd_idmap_get_gid_from_rid(
@ -974,6 +1012,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
result = WINBINDD_OK;
done:
talloc_destroy(mem_ctx);
return result;

View File

@ -1,10 +1,11 @@
/*
Unix SMB/Netbios implementation.
Version 2.0
Version 2.2
Winbind daemon - user related functions
Copyright (C) Tim Potter 2000
Copyright (C) Jeremy Allison 2001.
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
@ -96,8 +97,7 @@ static struct winbindd_pw negative_pw_cache_entry;
/* Return a password structure from a username. Specify whether cached data
can be returned. */
enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
*state)
enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state *state)
{
uint32 user_rid, group_rid;
SAM_USERINFO_CTR *user_info;