Idmap NSS headers
Copyright (C) Gerald Carter 2006
+ Copyright (C) Michael Adam 2008
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
*/
#include "includes.h"
+#include "ads.h"
#include "nss_info.h"
static struct nss_function_entry *backends = NULL;
+static struct nss_function_entry *default_backend = NULL;
static struct nss_domain_entry *nss_domain_list = NULL;
/**********************************************************************
static bool parse_nss_parm( const char *config, char **backend, char **domain )
{
char *p;
- char *q;
- int len;
*backend = *domain = NULL;
*domain = SMB_STRDUP( p+1 );
}
- len = PTR_DIFF(p,config)+1;
- if ( (q = SMB_MALLOC_ARRAY( char, len )) == NULL ) {
- SAFE_FREE( *backend );
- return False;
+ *backend = SMB_STRNDUP(config, PTR_DIFF(p, config));
+ return (*backend != NULL);
+}
+
+static NTSTATUS nss_domain_list_add_domain(const char *domain,
+ struct nss_function_entry *nss_backend)
+{
+ struct nss_domain_entry *nss_domain;
+
+ nss_domain = talloc_zero(nss_domain_list, struct nss_domain_entry);
+ if (!nss_domain) {
+ DEBUG(0, ("nss_domain_list_add_domain: talloc() failure!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ nss_domain->backend = nss_backend;
+ if (domain) {
+ nss_domain->domain = talloc_strdup(nss_domain, domain);
+ if (!nss_domain->domain) {
+ DEBUG(0, ("nss_domain_list_add_domain: talloc() "
+ "failure!\n"));
+ TALLOC_FREE(nss_domain);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ nss_domain->init_status = nss_domain->backend->methods->init(nss_domain);
+ if (!NT_STATUS_IS_OK(nss_domain->init_status)) {
+ DEBUG(0, ("nss_init: Failed to init backend '%s' for domain "
+ "'%s'!\n", nss_backend->name, nss_domain->domain));
}
- StrnCpy( q, config, len-1);
- q[len-1] = '\0';
- *backend = q;
+ DLIST_ADD(nss_domain_list, nss_domain);
- return True;
+ DEBUG(10, ("Added domain '%s' with backend '%s' to nss_domain_list.\n",
+ domain, nss_backend->name));
+
+ return NT_STATUS_OK;
}
/********************************************************************
to initialize the state on a per domain basis.
*******************************************************************/
- NTSTATUS nss_init( const char **nss_list )
+static NTSTATUS nss_init(const char **nss_list)
{
NTSTATUS status;
- static NTSTATUS nss_initialized = NT_STATUS_UNSUCCESSFUL;
+ static bool nss_initialized = false;
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) )
+ if (nss_initialized) {
return NT_STATUS_OK;
+ }
- /* The "template" backend should alqays be registered as it
+ /* The "template" backend should always be registered as it
is a static module */
- if ( (nss_backend = nss_get_backend( "template" )) == NULL ) {
+ nss_backend = nss_get_backend("template");
+ if (nss_backend == NULL) {
static_init_nss_info;
}
/* validate the backend */
- if ( (nss_backend = nss_get_backend( backend )) == NULL ) {
- /* attempt to register the backend */
- status = smb_probe_module( "nss_info", backend );
+ nss_backend = nss_get_backend(backend);
+ if (nss_backend == NULL) {
+ /*
+ * This is a freaking hack. We don't have proper
+ * modules for nss_info backends. Right now we have
+ * our standard nss_info backends in the ad backend.
+ */
+ status = smb_probe_module("idmap", "ad");
if ( !NT_STATUS_IS_OK(status) ) {
continue;
}
+ }
- /* try again */
- if ( (nss_backend = nss_get_backend( backend )) == NULL ) {
- DEBUG(0,("nss_init: unregistered backend %s!. Skipping\n",
- backend));
+ nss_backend = nss_get_backend(backend);
+ if (nss_backend == NULL) {
+ /* attempt to register the backend */
+ status = smb_probe_module( "nss_info", backend );
+ if ( !NT_STATUS_IS_OK(status) ) {
continue;
}
}
- /* fill in the nss_domain_entry and add it to the
- list of domains */
-
- nss_domain = TALLOC_ZERO_P( nss_domain_list, struct nss_domain_entry );
- if ( !nss_domain ) {
- DEBUG(0,("nss_init: talloc() failure!\n"));
- return NT_STATUS_NO_MEMORY;
+ /* try again */
+ nss_backend = nss_get_backend(backend);
+ if (nss_backend == NULL) {
+ DEBUG(0, ("nss_init: unregistered backend %s!. "
+ "Skipping\n", backend));
+ continue;
}
- nss_domain->backend = nss_backend;
- nss_domain->domain = talloc_strdup( nss_domain, domain );
-
- /* Try to init and ave the result */
-
- nss_domain->init_status = nss_domain->backend->methods->init( nss_domain );
- DLIST_ADD( nss_domain_list, nss_domain );
- if ( !NT_STATUS_IS_OK(nss_domain->init_status) ) {
- DEBUG(0,("nss_init: Failed to init backend for %s domain!\n",
- nss_domain->domain));
+ /*
+ * The first config item of the list without an explicit domain
+ * is treated as the default nss info backend.
+ */
+ if ((domain == NULL) && (default_backend == NULL)) {
+ DEBUG(10, ("nss_init: using '%s' as default backend.\n",
+ backend));
+ default_backend = nss_backend;
}
- DEBUG(10, ("nss_init: nss domain initialized: "
- "domain = '%s', backend = '%s'\n",
- domain, backend));
+ status = nss_domain_list_add_domain(domain, nss_backend);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
/* cleanup */
"Defaulting to \"template\".\n"));
- /* we shouild default to use template here */
+ /* we should default to use template here */
}
- nss_initialized = NT_STATUS_OK;
+ nss_initialized = true;
return NT_STATUS_OK;
}
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)));
+ DEBUG(4,("find_nss_domain: Failed to init nss_info API "
+ "(%s)!\n", nt_errstr(status)));
return NULL;
}
break;
}
- /* If we didn't find a match, then use the default nss info */
+ /* If we didn't find a match, then use the default nss backend */
if ( !p ) {
- if ( !nss_domain_list ) {
+ if (!default_backend) {
+ return NULL;
+ }
+
+ status = nss_domain_list_add_domain(domain, default_backend);
+ if (!NT_STATUS_IS_OK(status)) {
return NULL;
}
+ /*
+ * HACK ALERT:
+ * Here, we use the fact that the new domain was added at
+ * the beginning of the list...
+ */
p = nss_domain_list;
}
/********************************************************************
*******************************************************************/
- NTSTATUS nss_get_info( const char *domain, const DOM_SID *user_sid,
+NTSTATUS nss_get_info( const char *domain, const struct dom_sid *user_sid,
TALLOC_CTX *ctx,
- ADS_STRUCT *ads, LDAPMessage *msg,
- char **homedir, char **shell, char **gecos,
- gid_t *p_gid)
+ const char **homedir, const char **shell,
+ const char **gecos, gid_t *p_gid)
{
struct nss_domain_entry *p;
struct nss_info_methods *m;
m = p->backend->methods;
- return m->get_nss_info( p, user_sid, ctx, ads, msg,
+ return m->get_nss_info( p, user_sid, ctx,
homedir, shell, gecos, p_gid );
}