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;
int compat = 0;
int i;
- if (idmap_ctx) {
- return NT_STATUS_OK;
- }
+ /* Always initialize the cache. We'll have to delay initialization
+ of backends if we are offline */
- if ( (idmap_ctx = talloc_named_const(NULL, 0, "idmap_ctx")) == NULL ) {
- return NT_STATUS_NO_MEMORY;
+ 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_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;
/* 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;
}
/* 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);
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"));
/* 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);
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"
/* 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;
/* 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;
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 */
}
+ nss_initialized = NT_STATUS_OK;
+
return NT_STATUS_OK;
}
/********************************************************************
*******************************************************************/
- NTSTATUS nss_get_info( const char *domain, const DOM_SID *user_sid,
- TALLOC_CTX *ctx,
- ADS_STRUCT *ads, LDAPMessage *msg,
- char **homedir, char **shell, char **gecos,
- gid_t *p_gid)
+static struct nss_domain_entry *find_nss_domain( const char *domain )
{
+ NTSTATUS status;
struct nss_domain_entry *p;
- struct nss_info_methods *m;
+
+ 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 ) )
if ( !p ) {
if ( !nss_domain_list ) {
- return NT_STATUS_NOT_FOUND;
+ return NULL;
}
p = nss_domain_list;
}
+ return p;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+ NTSTATUS nss_get_info( const char *domain, const DOM_SID *user_sid,
+ TALLOC_CTX *ctx,
+ ADS_STRUCT *ads, LDAPMessage *msg,
+ char **homedir, char **shell, char **gecos,
+ gid_t *p_gid)
+{
+ struct nss_domain_entry *p;
+ struct nss_info_methods *m;
+
+ 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;
+ }
+
m = p->backend->methods;
return m->get_nss_info( p, user_sid, ctx, ads, msg,
/* 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. */
pidfile_create("winbindd");
+#if 0 /* not finished yet */
/* Ensure all cache and idmap caches are consistent
before we startup. */
}
return execve(argv[0], argv, envp);
}
+#endif
#if HAVE_SETPGID
/*
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,
}
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;
}
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) {