1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r21616: Delay initialization of idmap and nss_info backends until necessary

so they can honor the offline logon state.
This commit is contained in:
Gerald Carter 2007-03-01 03:16:38 +00:00 committed by Gerald (Jerry) Carter
parent 5575845952
commit 15b13dfe81
6 changed files with 200 additions and 40 deletions

View File

@ -225,9 +225,36 @@ NTSTATUS idmap_close(void)
static const char *idmap_default_domain[] = { "default domain", NULL };
/****************************************************************************
****************************************************************************/
NTSTATUS idmap_init_cache(void)
{
/* Always initialize the cache. We'll have to delay initialization
of backends if we are offline */
if ( idmap_ctx ) {
return NT_STATUS_OK;
}
if ( (idmap_ctx = talloc_named_const(NULL, 0, "idmap_ctx")) == NULL ) {
return NT_STATUS_NO_MEMORY;
}
if ( (idmap_cache = idmap_cache_init(idmap_ctx)) == NULL ) {
return NT_STATUS_UNSUCCESSFUL;
}
return NT_STATUS_OK;
}
/****************************************************************************
****************************************************************************/
NTSTATUS idmap_init(void)
{
NTSTATUS ret;
static NTSTATUS backend_init_status = NT_STATUS_UNSUCCESSFUL;
struct idmap_domain *dom;
char *compat_backend = NULL;
char *compat_params = NULL;
@ -238,16 +265,23 @@ NTSTATUS idmap_init(void)
int compat = 0;
int i;
if (idmap_ctx) {
/* Always initialize the cache. We'll have to delay initialization
of backends if we are offline */
ret = idmap_init_cache();
if ( !NT_STATUS_IS_OK(ret) )
return ret;
if ( NT_STATUS_IS_OK(backend_init_status) ) {
return NT_STATUS_OK;
}
/* We can't reliably call intialization code here unless
we are online */
if ( (idmap_ctx = talloc_named_const(NULL, 0, "idmap_ctx")) == NULL ) {
return NT_STATUS_NO_MEMORY;
}
if ( (idmap_cache = idmap_cache_init(idmap_ctx)) == NULL ) {
return NT_STATUS_UNSUCCESSFUL;
if ( get_global_winbindd_state_offline() ) {
backend_init_status = NT_STATUS_FILE_IS_OFFLINE;
return backend_init_status;
}
static_init_idmap;
@ -559,11 +593,17 @@ NTSTATUS idmap_init(void)
/* cleanpu temporary strings */
TALLOC_FREE( compat_backend );
backend_init_status = NT_STATUS_OK;
return NT_STATUS_OK;
done:
DEBUG(0, ("Aborting IDMAP Initialization ...\n"));
idmap_close();
/* save the init status for later checks */
backend_init_status = ret;
return ret;
}
@ -1067,6 +1107,14 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids)
/* let's see if there is any id mapping to be retieved from the backends */
if (bi) {
/* Only do query if we are online */
if ( lp_winbind_offline_logon() &&
get_global_winbindd_state_offline() )
{
ret = NT_STATUS_FILE_IS_OFFLINE;
goto done;
}
ret = idmap_backends_unixids_to_sids(bids);
IDMAP_CHECK_RET(ret);
@ -1132,7 +1180,8 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids)
if ( ! NT_STATUS_IS_OK(ret)) {
if ( ! bids) {
/* alloc space for ids to be resolved by backends (realloc ten by ten) */
/* alloc space for ids to be resolved
by backends (realloc ten by ten) */
bids = talloc_array(ctx, struct id_map *, 10);
if ( ! bids) {
DEBUG(1, ("Out of memory!\n"));
@ -1164,6 +1213,14 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids)
/* let's see if there is any id mapping to be retieved from the backends */
if (bids) {
/* Only do query if we are online */
if ( lp_winbind_offline_logon() &&
get_global_winbindd_state_offline() )
{
ret = NT_STATUS_FILE_IS_OFFLINE;
goto done;
}
ret = idmap_backends_sids_to_unixids(bids);
IDMAP_CHECK_RET(ret);

View File

@ -22,6 +22,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/
#include "includes.h"
#include "winbindd.h"
#define TIMEOUT_LEN 12
#define IDMAP_CACHE_DATA_FMT "%12u/%s"
@ -418,14 +419,34 @@ NTSTATUS idmap_cache_map_sid(struct idmap_cache_ctx *cache, struct id_map *id)
/* here ret == NT_STATUS_OK and id->status = ID_MAPPED */
if (t <= time(NULL)) {
/* We're expired, set an error code for upper layer */
ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
/* If we've been told to be offline - stay in
that state... */
if (lp_winbind_offline_logon() &&
get_global_winbindd_state_offline())
{
DEBUG(10,("idmap_cache_map_sid: winbindd is "
"globally offline.\n"));
} else {
/* We're expired, set an error code
for upper layer */
ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
}
}
} else {
if (t <= time(NULL)) {
/* We're expired, delete the entry and return not mapped */
tdb_delete(cache->tdb, keybuf);
ret = NT_STATUS_NONE_MAPPED;
/* If we've been told to be offline - stay in
that state... */
if (lp_winbind_offline_logon() &&
get_global_winbindd_state_offline())
{
DEBUG(10,("idmap_cache_map_sid: winbindd is "
"globally offline.\n"));
} else {
/* We're expired, delete the entry and return
not mapped */
tdb_delete(cache->tdb, keybuf);
ret = NT_STATUS_NONE_MAPPED;
}
} else {
/* this is not mapped as it was a negative cache hit */
id->status = ID_UNMAPPED;
@ -508,14 +529,34 @@ NTSTATUS idmap_cache_map_id(struct idmap_cache_ctx *cache, struct id_map *id)
/* here ret == NT_STATUS_OK and id->mapped = True */
if (t <= time(NULL)) {
/* We're expired, set an error code for upper layer */
ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
/* If we've been told to be offline - stay in
that state... */
if (lp_winbind_offline_logon() &&
get_global_winbindd_state_offline())
{
DEBUG(10,("idmap_cache_map_sid: winbindd is "
"globally offline.\n"));
} else {
/* We're expired, set an error code
for upper layer */
ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
}
}
} else {
if (t <= time(NULL)) {
/* We're expired, delete the entry and return not mapped */
tdb_delete(cache->tdb, keybuf);
ret = NT_STATUS_NONE_MAPPED;
/* If we've been told to be offline - stay in
that state... */
if (lp_winbind_offline_logon() &&
get_global_winbindd_state_offline())
{
DEBUG(10,("idmap_cache_map_sid: winbindd is "
"globally offline.\n"));
} else {
/* We're expired, delete the entry and
return not mapped */
tdb_delete(cache->tdb, keybuf);
ret = NT_STATUS_NONE_MAPPED;
}
} else {
/* this is not mapped is it was a negative cache hit */
id->status = ID_UNMAPPED;

View File

@ -131,11 +131,17 @@ static BOOL parse_nss_parm( const char *config, char **backend, char **domain )
NTSTATUS nss_init( const char **nss_list )
{
NTSTATUS status;
static NTSTATUS nss_initialized = NT_STATUS_UNSUCCESSFUL;
int i;
char *backend, *domain;
struct nss_function_entry *nss_backend;
struct nss_domain_entry *nss_domain;
/* check for previous successful initializations */
if ( NT_STATUS_IS_OK(nss_initialized) )
return NT_STATUS_OK;
/* The "template" backend should alqays be registered as it
is a static module */
@ -207,9 +213,44 @@ static BOOL parse_nss_parm( const char *config, char **backend, char **domain )
}
nss_initialized = NT_STATUS_OK;
return NT_STATUS_OK;
}
/********************************************************************
*******************************************************************/
static struct nss_domain_entry *find_nss_domain( const char *domain )
{
NTSTATUS status;
struct nss_domain_entry *p;
status = nss_init( lp_winbind_nss_info() );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(4,("nss_get_info: Failed to init nss_info API (%s)!\n",
nt_errstr(status)));
return NULL;
}
for ( p=nss_domain_list; p; p=p->next ) {
if ( strequal( p->domain, domain ) )
break;
}
/* If we didn't find a match, then use the default nss info */
if ( !p ) {
if ( !nss_domain_list ) {
return NULL;
}
p = nss_domain_list;
}
return p;
}
/********************************************************************
*******************************************************************/
@ -221,22 +262,13 @@ static BOOL parse_nss_parm( const char *config, char **backend, char **domain )
{
struct nss_domain_entry *p;
struct nss_info_methods *m;
for ( p=nss_domain_list; p; p=p->next ) {
if ( strequal( p->domain, domain ) )
break;
}
/* If we didn't find a match, then use the default nss info */
if ( !p ) {
if ( !nss_domain_list ) {
return NT_STATUS_NOT_FOUND;
}
if ( (p = find_nss_domain( domain )) == NULL ) {
DEBUG(4,("nss_get_info: Failed to find nss domain pointer for %s\n",
domain ));
return NT_STATUS_NOT_FOUND;
}
p = nss_domain_list;
}
m = p->backend->methods;
return m->get_nss_info( p, user_sid, ctx, ads, msg,

View File

@ -1011,14 +1011,10 @@ int main(int argc, char **argv, char **envp)
/* Winbind daemon initialisation */
if ( ! NT_STATUS_IS_OK(idmap_init()) ) {
DEBUG(1, ("Could not init idmap! - Sid/[UG]id mapping will not be available\n"));
if ( ! NT_STATUS_IS_OK(idmap_init_cache()) ) {
DEBUG(1, ("Could not init idmap cache!\n"));
}
#ifdef WITH_ADS
nss_init( lp_winbind_nss_info() );
#endif
/* Unblock all signals we are interested in as they may have been
blocked by the parent process. */
@ -1047,6 +1043,7 @@ int main(int argc, char **argv, char **envp)
pidfile_create("winbindd");
#if 0 /* not finished yet */
/* Ensure all cache and idmap caches are consistent
before we startup. */
@ -1060,6 +1057,7 @@ int main(int argc, char **argv, char **envp)
}
return execve(argv[0], argv, envp);
}
#endif
#if HAVE_SETPGID
/*

View File

@ -535,7 +535,7 @@ void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
request.cmd = WINBINDD_DUAL_SID2GID;
sid_to_string(request.data.dual_sid2id.sid, sid);
DEBUG(7,("idmap_sid2gid_async: Resolving %s to a gid\n",
DEBUG(7,("winbindd_sid2gid_async: Resolving %s to a gid\n",
request.data.dual_sid2id.sid));
do_async(mem_ctx, idmap_child(), &request, winbindd_sid2gid_recv,

View File

@ -502,10 +502,26 @@ void winbind_msg_offline(int msg_type, struct process_id src,
}
DEBUG(5,("winbind_msg_offline: marking %s offline.\n", domain->name));
set_domain_offline(domain);
/* Send an offline message to the idmap child when our
primary domain goes offline */
if ( domain->primary ) {
struct winbindd_child *idmap = idmap_child();
if ( idmap->pid != 0 ) {
message_send_pid(pid_to_procid(idmap->pid),
MSG_WINBIND_OFFLINE,
domain->name,
strlen(domain->name)+1,
False);
}
}
}
for (child = children; child != NULL; child = child->next) {
/* Don't send message to idmap child. */
/* Don't send message to idmap child. We've already
done so above. */
if (!child->domain || (child == idmap_child())) {
continue;
}
@ -556,6 +572,22 @@ void winbind_msg_online(int msg_type, struct process_id src,
winbindd_flush_negative_conn_cache(domain);
set_domain_online_request(domain);
/* Send an offline message to the idmap child when our
primary domain goes offline */
if ( domain->primary ) {
struct winbindd_child *idmap = idmap_child();
if ( idmap->pid != 0 ) {
message_send_pid(pid_to_procid(idmap->pid),
MSG_WINBIND_ONLINE,
domain->name,
strlen(domain->name)+1,
False);
}
}
}
for (child = children; child != NULL; child = child->next) {