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:
parent
5575845952
commit
15b13dfe81
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
/*
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user