summaryrefslogtreecommitdiff
path: root/source/winbindd
diff options
context:
space:
mode:
Diffstat (limited to 'source/winbindd')
-rw-r--r--source/winbindd/idmap.c1639
-rw-r--r--source/winbindd/idmap_ad.c197
-rw-r--r--source/winbindd/idmap_adex/cell_util.c292
-rw-r--r--source/winbindd/idmap_adex/domain_util.c278
-rw-r--r--source/winbindd/idmap_adex/gc_util.c848
-rw-r--r--source/winbindd/idmap_adex/idmap_adex.c460
-rw-r--r--source/winbindd/idmap_adex/idmap_adex.h257
-rw-r--r--source/winbindd/idmap_adex/likewise_cell.c425
-rw-r--r--source/winbindd/idmap_adex/provider_unified.c1180
-rw-r--r--source/winbindd/idmap_cache.c534
-rw-r--r--source/winbindd/idmap_hash/idmap_hash.c393
-rw-r--r--source/winbindd/idmap_hash/idmap_hash.h60
-rw-r--r--source/winbindd/idmap_hash/mapfile.c175
-rw-r--r--source/winbindd/idmap_ldap.c104
-rw-r--r--source/winbindd/idmap_nss.c12
-rw-r--r--source/winbindd/idmap_passdb.c11
-rw-r--r--source/winbindd/idmap_rid.c20
-rw-r--r--source/winbindd/idmap_tdb.c121
-rw-r--r--source/winbindd/idmap_tdb2.c384
-rw-r--r--source/winbindd/idmap_util.c194
-rw-r--r--source/winbindd/nss_info.c41
-rw-r--r--source/winbindd/nss_info_template.c32
-rw-r--r--source/winbindd/winbindd.c50
-rw-r--r--source/winbindd/winbindd.h11
-rw-r--r--source/winbindd/winbindd_ads.c2
-rw-r--r--source/winbindd/winbindd_async.c2
-rw-r--r--source/winbindd/winbindd_cache.c255
-rw-r--r--source/winbindd/winbindd_cm.c209
-rw-r--r--source/winbindd/winbindd_dual.c20
-rw-r--r--source/winbindd/winbindd_group.c638
-rw-r--r--source/winbindd/winbindd_idmap.c172
-rw-r--r--source/winbindd/winbindd_locator.c46
-rw-r--r--source/winbindd/winbindd_misc.c9
-rw-r--r--source/winbindd/winbindd_pam.c560
-rw-r--r--source/winbindd/winbindd_proto.h615
-rw-r--r--source/winbindd/winbindd_rpc.c48
-rw-r--r--source/winbindd/winbindd_sid.c223
-rw-r--r--source/winbindd/winbindd_user.c351
-rw-r--r--source/winbindd/winbindd_util.c175
39 files changed, 3291 insertions, 7752 deletions
diff --git a/source/winbindd/idmap.c b/source/winbindd/idmap.c
index cfc5597f42..d601210ecf 100644
--- a/source/winbindd/idmap.c
+++ b/source/winbindd/idmap.c
@@ -28,58 +28,52 @@
static_decl_idmap;
-/**
- * Pointer to the backend methods. Modules register themselves here via
- * smb_register_idmap.
- */
-
struct idmap_backend {
const char *name;
struct idmap_methods *methods;
struct idmap_backend *prev, *next;
};
-static struct idmap_backend *backends = NULL;
-/**
- * Pointer to the alloc backend methods. Modules register themselves here via
- * smb_register_idmap_alloc.
- */
struct idmap_alloc_backend {
const char *name;
struct idmap_alloc_methods *methods;
struct idmap_alloc_backend *prev, *next;
};
-static struct idmap_alloc_backend *alloc_backends = NULL;
-/**
- * The idmap alloc context that is configured via "idmap alloc
- * backend". Defaults to "idmap backend" in case the module (tdb, ldap) also
- * provides alloc methods.
- */
+struct idmap_cache_ctx;
+
struct idmap_alloc_context {
+ const char *params;
struct idmap_alloc_methods *methods;
+ bool initialized;
};
-static struct idmap_alloc_context *idmap_alloc_ctx = NULL;
-/**
- * Default idmap domain configured via "idmap backend".
- */
-static struct idmap_domain *default_idmap_domain;
-
-/**
- * Passdb idmap domain, not configurable. winbind must always give passdb a
- * chance to map ids.
- */
-static struct idmap_domain *passdb_idmap_domain;
-
-/**
- * List of specially configured idmap domains. This list is filled on demand
- * in the winbind idmap child when the parent winbind figures out via the
- * special range parameter or via the domain SID that a special "idmap config
- * domain" configuration is present.
- */
+static TALLOC_CTX *idmap_ctx = NULL;
+static struct idmap_cache_ctx *idmap_cache;
+
+static struct idmap_backend *backends = NULL;
static struct idmap_domain **idmap_domains = NULL;
static int num_domains = 0;
+static int pdb_dom_num = -1;
+static int def_dom_num = -1;
+
+static struct idmap_alloc_backend *alloc_backends = NULL;
+static struct idmap_alloc_context *idmap_alloc_ctx = NULL;
+
+#define IDMAP_CHECK_RET(ret) do { \
+ if ( ! NT_STATUS_IS_OK(ret)) { \
+ DEBUG(2, ("ERROR: NTSTATUS = 0x%08x\n", NT_STATUS_V(ret))); \
+ goto done; \
+ } } while(0)
+#define IDMAP_REPORT_RET(ret) do { \
+ if ( ! NT_STATUS_IS_OK(ret)) { \
+ DEBUG(2, ("ERROR: NTSTATUS = 0x%08x\n", NT_STATUS_V(ret))); \
+ } } while(0)
+#define IDMAP_CHECK_ALLOC(mem) do { \
+ if (!mem) { \
+ DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; \
+ goto done; \
+ } } while(0)
static struct idmap_methods *get_methods(const char *name)
{
@@ -113,11 +107,6 @@ bool idmap_is_offline(void)
get_global_winbindd_state_offline() );
}
-bool idmap_is_online(void)
-{
- return !idmap_is_offline();
-}
-
/**********************************************************************
Allow a module to register itself as a method.
**********************************************************************/
@@ -125,8 +114,13 @@ bool idmap_is_online(void)
NTSTATUS smb_register_idmap(int version, const char *name,
struct idmap_methods *methods)
{
+ struct idmap_methods *test;
struct idmap_backend *entry;
+ if (!idmap_ctx) {
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+
if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
DEBUG(0, ("Failed to register idmap module.\n"
"The module was compiled against "
@@ -143,24 +137,20 @@ NTSTATUS smb_register_idmap(int version, const char *name,
return NT_STATUS_INVALID_PARAMETER;
}
- for (entry = backends; entry != NULL; entry = entry->next) {
- if (strequal(entry->name, name)) {
- DEBUG(0,("Idmap module %s already registered!\n",
- name));
- return NT_STATUS_OBJECT_NAME_COLLISION;
- }
+ test = get_methods(name);
+ if (test) {
+ DEBUG(0,("Idmap module %s already registered!\n", name));
+ return NT_STATUS_OBJECT_NAME_COLLISION;
}
- entry = talloc(NULL, struct idmap_backend);
+ entry = talloc(idmap_ctx, struct idmap_backend);
if ( ! entry) {
DEBUG(0,("Out of memory!\n"));
- TALLOC_FREE(entry);
return NT_STATUS_NO_MEMORY;
}
- entry->name = talloc_strdup(entry, name);
+ entry->name = talloc_strdup(idmap_ctx, name);
if ( ! entry->name) {
DEBUG(0,("Out of memory!\n"));
- TALLOC_FREE(entry);
return NT_STATUS_NO_MEMORY;
}
entry->methods = methods;
@@ -171,7 +161,7 @@ NTSTATUS smb_register_idmap(int version, const char *name,
}
/**********************************************************************
- Allow a module to register itself as an alloc method.
+ Allow a module to register itself as a method.
**********************************************************************/
NTSTATUS smb_register_idmap_alloc(int version, const char *name,
@@ -180,6 +170,10 @@ NTSTATUS smb_register_idmap_alloc(int version, const char *name,
struct idmap_alloc_methods *test;
struct idmap_alloc_backend *entry;
+ if (!idmap_ctx) {
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+
if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
DEBUG(0, ("Failed to register idmap alloc module.\n"
"The module was compiled against "
@@ -202,12 +196,12 @@ NTSTATUS smb_register_idmap_alloc(int version, const char *name,
return NT_STATUS_OBJECT_NAME_COLLISION;
}
- entry = talloc(NULL, struct idmap_alloc_backend);
+ entry = talloc(idmap_ctx, struct idmap_alloc_backend);
if ( ! entry) {
DEBUG(0,("Out of memory!\n"));
return NT_STATUS_NO_MEMORY;
}
- entry->name = talloc_strdup(entry, name);
+ entry->name = talloc_strdup(idmap_ctx, name);
if ( ! entry->name) {
DEBUG(0,("Out of memory!\n"));
return NT_STATUS_NO_MEMORY;
@@ -231,560 +225,1349 @@ static int close_domain_destructor(struct idmap_domain *dom)
return 0;
}
-static bool parse_idmap_module(TALLOC_CTX *mem_ctx, const char *param,
- char **pmodulename, char **pargs)
-{
- char *modulename;
- char *args;
+/**************************************************************************
+ Shutdown.
+**************************************************************************/
- if (strncmp(param, "idmap_", 6) == 0) {
- param += 6;
- DEBUG(1, ("idmap_init: idmap backend uses deprecated "
- "'idmap_' prefix. Please replace 'idmap_%s' by "
- "'%s'\n", param, param));
+NTSTATUS idmap_close(void)
+{
+ /* close the alloc backend first before freeing idmap_ctx */
+ if (idmap_alloc_ctx) {
+ idmap_alloc_ctx->methods->close_fn();
+ idmap_alloc_ctx->methods = NULL;
}
+ alloc_backends = NULL;
- modulename = talloc_strdup(mem_ctx, param);
- if (modulename == NULL) {
- return false;
- }
+ /* this talloc_free call will fire the talloc destructors
+ * that will free all active backends resources */
+ TALLOC_FREE(idmap_ctx);
+ idmap_cache = NULL;
+ idmap_domains = NULL;
+ backends = NULL;
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ ****************************************************************************/
+
+NTSTATUS idmap_init_cache(void)
+{
+ /* Always initialize the cache. We'll have to delay initialization
+ of backends if we are offline */
- args = strchr(modulename, ':');
- if (args == NULL) {
- *pmodulename = modulename;
- *pargs = NULL;
- return true;
+ if ( idmap_ctx ) {
+ return NT_STATUS_OK;
}
- *args = '\0';
+ if ( (idmap_ctx = talloc_named_const(NULL, 0, "idmap_ctx")) == NULL ) {
+ return NT_STATUS_NO_MEMORY;
+ }
- args = talloc_strdup(mem_ctx, args+1);
- if (args == NULL) {
- TALLOC_FREE(modulename);
- return false;
+ if ( (idmap_cache = idmap_cache_init(idmap_ctx)) == NULL ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- *pmodulename = modulename;
- *pargs = args;
- return true;
+ return NT_STATUS_OK;
}
-/**
- * Initialize a domain structure
- * @param[in] mem_ctx memory context for the result
- * @param[in] domainname which domain is this for
- * @param[in] modulename which backend module
- * @param[in] params parameter to pass to the init function
- * @result The initialized structure
- */
-static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx,
- const char *domainname,
- const char *modulename,
- const char *params)
+/****************************************************************************
+ ****************************************************************************/
+
+NTSTATUS idmap_init(void)
{
- struct idmap_domain *result;
- NTSTATUS status;
+ NTSTATUS ret;
+ static NTSTATUS idmap_init_status = NT_STATUS_UNSUCCESSFUL;
+ struct idmap_domain *dom;
+ char *compat_backend = NULL;
+ char *compat_params = NULL;
+ const char **dom_list = NULL;
+ const char *default_domain = NULL;
+ char *alloc_backend = NULL;
+ bool default_already_defined = False;
+ bool pri_dom_is_in_list = False;
+ int compat = 0;
+ int i;
- result = talloc_zero(mem_ctx, struct idmap_domain);
- if (result == NULL) {
- DEBUG(0, ("talloc failed\n"));
- return NULL;
+ ret = idmap_init_cache();
+ if (!NT_STATUS_IS_OK(ret))
+ return ret;
+
+ if (NT_STATUS_IS_OK(idmap_init_status)) {
+ return NT_STATUS_OK;
}
- result->name = talloc_strdup(result, domainname);
- if (result->name == NULL) {
- DEBUG(0, ("talloc failed\n"));
- goto fail;
+ /* We can't reliably call intialization code here unless
+ we are online. But return NT_STATUS_OK so the upper
+ level code doesn't abort idmap lookups. */
+
+ if ( get_global_winbindd_state_offline() ) {
+ idmap_init_status = NT_STATUS_FILE_IS_OFFLINE;
+ return NT_STATUS_OK;
}
- result->methods = get_methods(modulename);
- if (result->methods == NULL) {
- DEBUG(3, ("idmap backend %s not found\n", modulename));
+ static_init_idmap;
- status = smb_probe_module("idmap", modulename);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("Could not probe idmap module %s\n",
- modulename));
- goto fail;
+ dom_list = lp_idmap_domains();
+
+ if ( lp_idmap_backend() ) {
+ const char **compat_list = lp_idmap_backend();
+ char *p = NULL;
+ const char *q = NULL;
+
+ if ( dom_list ) {
+ DEBUG(0, ("WARNING: idmap backend and idmap domains are"
+ " mutually exclusive!\n"));
+ DEBUGADD(0,("idmap backend option will be IGNORED!\n"));
+ } else {
+ compat = 1;
+
+ compat_backend = talloc_strdup(idmap_ctx, *compat_list);
+
+ /* strip any leading idmap_ prefix of */
+ if (strncmp(*compat_list, "idmap_", 6) == 0 ) {
+ q = *compat_list += 6;
+ DEBUG(0, ("WARNING: idmap backend uses obsolete"
+ " and deprecated 'idmap_' prefix.\n"
+ "Please replace 'idmap_%s' by '%s' in"
+ " %s\n", q, q, get_dyn_CONFIGFILE()));
+ compat_backend = talloc_strdup(idmap_ctx, q);
+ } else {
+ compat_backend = talloc_strdup(idmap_ctx,
+ *compat_list);
+ }
+
+ if (compat_backend == NULL ) {
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ /* separate the backend and module arguements */
+ if ((p = strchr(compat_backend, ':')) != NULL) {
+ *p = '\0';
+ compat_params = p + 1;
+ }
}
+ } else if ( !dom_list ) {
+ /* Back compatible: without idmap domains and explicit
+ idmap backend. Taking default idmap backend: tdb */
- result->methods = get_methods(modulename);
- }
- if (result->methods == NULL) {
- DEBUG(1, ("idmap backend %s not found\n", modulename));
- goto fail;
+ compat = 1;
+ compat_backend = talloc_strdup( idmap_ctx, "tdb");
+ compat_params = compat_backend;
}
- status = result->methods->init(result, params);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("idmap initialization returned %s\n",
- nt_errstr(status)));
- goto fail;
+ if ( ! dom_list) {
+ /* generate a list with our main domain */
+ const char ** dl;
+
+ dl = talloc_array(idmap_ctx, const char *, 2);
+ if (dl == NULL) {
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ dl[0] = talloc_strdup(dl, lp_workgroup());
+ if (dl[0] == NULL) {
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ /* terminate */
+ dl[1] = NULL;
+
+ dom_list = dl;
+ default_domain = dl[0];
}
- talloc_set_destructor(result, close_domain_destructor);
+ /***************************
+ * initialize idmap domains
+ */
+ DEBUG(1, ("Initializing idmap domains\n"));
+
+ for (i=0, num_domains=0; dom_list[i]; i++) {
+ const char *parm_backend;
+ char *config_option;
+
+ /* ignore BUILTIN and local MACHINE domains */
+ if (strequal(dom_list[i], "BUILTIN")
+ || strequal(dom_list[i], get_global_sam_name()))
+ {
+ DEBUG(0,("idmap_init: Ignoring domain %s\n",
+ dom_list[i]));
+ continue;
+ }
- return result;
+ if ((dom_list[i] != default_domain) &&
+ strequal(dom_list[i], lp_workgroup())) {
+ pri_dom_is_in_list = True;
+ }
+ /* init domain */
-fail:
- TALLOC_FREE(result);
- return NULL;
-}
+ dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain);
+ IDMAP_CHECK_ALLOC(dom);
-/**
- * Initialize the default domain structure
- * @param[in] mem_ctx memory context for the result
- * @result The default domain structure
- *
- * This routine takes the module name from the "idmap backend" parameter,
- * passing a possible parameter like ldap:ldap://ldap-url/ to the module.
- */
+ dom->name = talloc_strdup(dom, dom_list[i]);
+ IDMAP_CHECK_ALLOC(dom->name);
-static struct idmap_domain *idmap_init_default_domain(TALLOC_CTX *mem_ctx)
-{
- struct idmap_domain *result;
- char *modulename;
- char *params;
+ config_option = talloc_asprintf(dom, "idmap config %s",
+ dom->name);
+ IDMAP_CHECK_ALLOC(config_option);
- DEBUG(10, ("idmap_init_default_domain: calling static_init_idmap\n"));
+ /* default or specific ? */
- static_init_idmap;
+ dom->default_domain = lp_parm_bool(-1, config_option,
+ "default", False);
- if (!parse_idmap_module(talloc_tos(), lp_idmap_backend(), &modulename,
- &params)) {
- DEBUG(1, ("parse_idmap_module failed\n"));
- return NULL;
- }
+ if (dom->default_domain ||
+ (default_domain && strequal(dom_list[i], default_domain))) {
- DEBUG(3, ("idmap_init: using '%s' as remote backend\n", modulename));
+ /* make sure this is set even when we match
+ * default_domain */
+ dom->default_domain = True;
- result = idmap_init_domain(mem_ctx, "*", modulename, params);
- if (result == NULL) {
- goto fail;
- }
+ if (default_already_defined) {
+ DEBUG(1, ("ERROR: Multiple domains defined as"
+ " default!\n"));
+ ret = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
- TALLOC_FREE(modulename);
- TALLOC_FREE(params);
- return result;
+ default_already_defined = True;
-fail:
- TALLOC_FREE(modulename);
- TALLOC_FREE(params);
- TALLOC_FREE(result);
- return NULL;
-}
+ }
-/**
- * Initialize a named domain structure
- * @param[in] mem_ctx memory context for the result
- * @param[in] domname the domain name
- * @result The default domain structure
- *
- * This routine looks at the "idmap config <domname>" parameters to figure out
- * the configuration.
- */
-
-static struct idmap_domain *idmap_init_named_domain(TALLOC_CTX *mem_ctx,
- const char *domname)
-{
- struct idmap_domain *result = NULL;
- char *config_option;
- const char *backend;
+ dom->readonly = lp_parm_bool(-1, config_option,
+ "readonly", False);
+
+ /* find associated backend (default: tdb) */
+ if (compat) {
+ parm_backend = talloc_strdup(idmap_ctx, compat_backend);
+ } else {
+ parm_backend = talloc_strdup(idmap_ctx,
+ lp_parm_const_string(
+ -1, config_option,
+ "backend", "tdb"));
+ }
+ IDMAP_CHECK_ALLOC(parm_backend);
- config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
- domname);
- if (config_option == NULL) {
- DEBUG(0, ("talloc failed\n"));
- goto fail;
- }
+ /* get the backend methods for this domain */
+ dom->methods = get_methods(parm_backend);
- backend = lp_parm_const_string(-1, config_option, "backend", NULL);
- if (backend == NULL) {
- DEBUG(1, ("no backend defined for %s\n", config_option));
- goto fail;
- }
+ if ( ! dom->methods) {
+ ret = smb_probe_module("idmap", parm_backend);
+ if (NT_STATUS_IS_OK(ret)) {
+ dom->methods = get_methods(parm_backend);
+ }
+ }
+ if ( ! dom->methods) {
+ DEBUG(0, ("ERROR: Could not get methods for "
+ "backend %s\n", parm_backend));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
- result = idmap_init_domain(mem_ctx, domname, backend, NULL);
- if (result == NULL) {
- goto fail;
- }
+ /* check the set_mapping function exists otherwise mark the
+ * module as readonly */
+ if ( ! dom->methods->set_mapping) {
+ DEBUG(5, ("Forcing to readonly, as this module can't"
+ " store arbitrary mappings.\n"));
+ dom->readonly = True;
+ }
- TALLOC_FREE(config_option);
- return result;
+ /* now that we have methods,
+ * set the destructor for this domain */
+ talloc_set_destructor(dom, close_domain_destructor);
-fail:
- TALLOC_FREE(config_option);
- TALLOC_FREE(result);
- return NULL;
-}
+ if (compat_params) {
+ dom->params = talloc_strdup(dom, compat_params);
+ IDMAP_CHECK_ALLOC(dom->params);
+ } else {
+ dom->params = NULL;
+ }
-/**
- * Initialize the passdb domain structure
- * @param[in] mem_ctx memory context for the result
- * @result The default domain structure
- *
- * No config, passdb has its own configuration.
- */
+ /* Finally instance a backend copy for this domain */
+ ret = dom->methods->init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ DEBUG(0, ("ERROR: Initialization failed for backend "
+ "%s (domain %s), deferred!\n",
+ parm_backend, dom->name));
+ }
+ idmap_domains = talloc_realloc(idmap_ctx, idmap_domains,
+ struct idmap_domain *, i+1);
+ if ( ! idmap_domains) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ idmap_domains[num_domains] = dom;
-static struct idmap_domain *idmap_init_passdb_domain(TALLOC_CTX *mem_ctx)
-{
- if (passdb_idmap_domain != NULL) {
- return passdb_idmap_domain;
- }
+ /* save default domain position for future uses */
+ if (dom->default_domain) {
+ def_dom_num = num_domains;
+ }
- passdb_idmap_domain = idmap_init_domain(NULL, get_global_sam_name(),
- "passdb", NULL);
- if (passdb_idmap_domain == NULL) {
- DEBUG(1, ("Could not init passdb idmap domain\n"));
- }
+ /* Bump counter to next available slot */
- return passdb_idmap_domain;
-}
+ num_domains++;
-/**
- * Find a domain struct according to a domain name
- * @param[in] domname Domain name to get the config for
- * @result The default domain structure that fits
- *
- * This is the central routine in the winbindd-idmap child to pick the correct
- * domain for looking up IDs. If domname is NULL or empty, we use the default
- * domain. If it contains something, we try to use idmap_init_named_domain()
- * to fetch the correct backend.
- *
- * The choice about "domname" is being made by the winbind parent, look at the
- * "have_idmap_config" of "struct winbindd_domain" which is set in
- * add_trusted_domain.
- */
-
-static struct idmap_domain *idmap_find_domain(const char *domname)
-{
- struct idmap_domain *result;
- int i;
+ DEBUG(10, ("Domain %s - Backend %s - %sdefault - %sreadonly\n",
+ dom->name, parm_backend,
+ dom->default_domain?"":"not ",
+ dom->readonly?"":"not "));
- /*
- * Always init the default domain, we can't go without one
- */
- if (default_idmap_domain == NULL) {
- default_idmap_domain = idmap_init_default_domain(NULL);
- }
- if (default_idmap_domain == NULL) {
- return NULL;
+ talloc_free(config_option);
}
- if ((domname == NULL) || (domname[0] == '\0')) {
- return default_idmap_domain;
- }
+ /* on DCs we need to add idmap_tdb as the default backend if compat is
+ * defined (when the old implicit configuration is used)
+ * This is not done in the previous loop a on member server we exclude
+ * the local domain. But on a DC the local domain is the only domain
+ * available therefore we are left with no default domain */
+ if (((lp_server_role() == ROLE_DOMAIN_PDC) ||
+ (lp_server_role() == ROLE_DOMAIN_BDC)) &&
+ ((num_domains == 0) && (compat == 1))) {
+
+ dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain);
+ IDMAP_CHECK_ALLOC(dom);
+
+ dom->name = talloc_strdup(dom, "__default__");
+ IDMAP_CHECK_ALLOC(dom->name);
+
+ dom->default_domain = True;
+ dom->readonly = False;
+
+ /* get the backend methods for this domain */
+ dom->methods = get_methods(compat_backend);
+ if ( ! dom->methods) {
+ ret = smb_probe_module("idmap", compat_backend);
+ if (NT_STATUS_IS_OK(ret)) {
+ dom->methods = get_methods(compat_backend);
+ }
+ }
+ if ( ! dom->methods) {
+ DEBUG(0, ("ERROR: Could not get methods for "
+ "backend %s\n", compat_backend));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
- for (i=0; i<num_domains; i++) {
- if (strequal(idmap_domains[i]->name, domname)) {
- return idmap_domains[i];
+ /* now that we have methods,
+ * set the destructor for this domain */
+ talloc_set_destructor(dom, close_domain_destructor);
+
+ dom->params = talloc_strdup(dom, compat_params);
+ IDMAP_CHECK_ALLOC(dom->params);
+
+ /* Finally instance a backend copy for this domain */
+ ret = dom->methods->init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ DEBUG(0, ("ERROR: Initialization failed for backend "
+ "%s (domain %s), deferred!\n",
+ compat_backend, dom->name));
}
- }
+ idmap_domains = talloc_realloc(idmap_ctx, idmap_domains,
+ struct idmap_domain *, 2);
+ if ( ! idmap_domains) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ idmap_domains[num_domains] = dom;
- if (idmap_domains == NULL) {
- /*
- * talloc context for all idmap domains
- */
- idmap_domains = TALLOC_ARRAY(NULL, struct idmap_domain *, 1);
- }
+ def_dom_num = num_domains;
- if (idmap_domains == NULL) {
- DEBUG(0, ("talloc failed\n"));
- return NULL;
- }
+ /* Bump counter to next available slot */
+
+ num_domains++;
- result = idmap_init_named_domain(idmap_domains, domname);
- if (result == NULL) {
- /*
- * Could not init that domain -- try the default one
- */
- return default_idmap_domain;
+ DEBUG(10, ("Domain %s - Backend %s - %sdefault - %sreadonly\n",
+ dom->name, compat_backend,
+ dom->default_domain?"":"not ",
+ dom->readonly?"":"not "));
}
- ADD_TO_ARRAY(idmap_domains, struct idmap_domain *, result,
- &idmap_domains, &num_domains);
- return result;
-}
+ /* automatically add idmap_nss backend if needed */
+ if ((lp_server_role() == ROLE_DOMAIN_MEMBER) &&
+ ( ! pri_dom_is_in_list) &&
+ lp_winbind_trusted_domains_only()) {
-void idmap_close(void)
-{
- if (idmap_alloc_ctx) {
- idmap_alloc_ctx->methods->close_fn();
- idmap_alloc_ctx->methods = NULL;
- }
- alloc_backends = NULL;
- TALLOC_FREE(default_idmap_domain);
- TALLOC_FREE(passdb_idmap_domain);
- TALLOC_FREE(idmap_domains);
- num_domains = 0;
-}
+ dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain);
+ IDMAP_CHECK_ALLOC(dom);
-/**
- * Initialize the idmap alloc backend
- * @param[out] ctx Where to put the alloc_ctx?
- * @result Did it work fine?
- *
- * This routine first looks at "idmap alloc backend" and if that is not
- * defined, it uses "idmap backend" for the module name.
- */
-static NTSTATUS idmap_alloc_init(struct idmap_alloc_context **ctx)
-{
- const char *backend;
- char *modulename, *params;
- NTSTATUS ret = NT_STATUS_NO_MEMORY;;
+ dom->name = talloc_strdup(dom, lp_workgroup());
+ IDMAP_CHECK_ALLOC(dom->name);
- if (idmap_alloc_ctx != NULL) {
- *ctx = idmap_alloc_ctx;
- return NT_STATUS_OK;
+ dom->default_domain = False;
+ dom->readonly = True;
+
+ /* get the backend methods for nss */
+ dom->methods = get_methods("nss");
+
+ /* (the nss module is always statically linked) */
+ if ( ! dom->methods) {
+ DEBUG(0, ("ERROR: No methods for idmap_nss ?!\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* now that we have methods,
+ * set the destructor for this domain */
+ talloc_set_destructor(dom, close_domain_destructor);
+
+ if (compat_params) {
+ dom->params = talloc_strdup(dom, compat_params);
+ IDMAP_CHECK_ALLOC(dom->params);
+ } else {
+ dom->params = NULL;
+ }
+
+ /* Finally instance a backend copy for this domain */
+ ret = dom->methods->init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ DEBUG(0, ("ERROR: Init. failed for idmap_nss ?!\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ idmap_domains = talloc_realloc(idmap_ctx,
+ idmap_domains,
+ struct idmap_domain *,
+ num_domains+1);
+ if ( ! idmap_domains) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ idmap_domains[num_domains] = dom;
+
+ DEBUG(10, ("Domain %s - Backend nss - not default - readonly\n",
+ dom->name ));
+
+ num_domains++;
}
- idmap_alloc_ctx = talloc(NULL, struct idmap_alloc_context);
- if (idmap_alloc_ctx == NULL) {
- DEBUG(0, ("talloc failed\n"));
- goto fail;
+ /**** automatically add idmap_passdb backend ****/
+ dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain);
+ IDMAP_CHECK_ALLOC(dom);
+
+ dom->name = talloc_strdup(dom, get_global_sam_name());
+ IDMAP_CHECK_ALLOC(dom->name);
+
+ dom->default_domain = False;
+ dom->readonly = True;
+
+ /* get the backend methods for passdb */
+ dom->methods = get_methods("passdb");
+
+ /* (the passdb module is always statically linked) */
+ if ( ! dom->methods) {
+ DEBUG(0, ("ERROR: No methods for idmap_passdb ?!\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- backend = lp_idmap_alloc_backend();
- if ((backend == NULL) || (backend[0] == '\0')) {
- backend = lp_idmap_backend();
+ /* now that we have methods, set the destructor for this domain */
+ talloc_set_destructor(dom, close_domain_destructor);
+
+ if (compat_params) {
+ dom->params = talloc_strdup(dom, compat_params);
+ IDMAP_CHECK_ALLOC(dom->params);
+ } else {
+ dom->params = NULL;
}
- if (backend == NULL) {
- DEBUG(3, ("no idmap alloc backend defined\n"));
- ret = NT_STATUS_INVALID_PARAMETER;
- goto fail;
+ /* Finally instance a backend copy for this domain */
+ ret = dom->methods->init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ DEBUG(0, ("ERROR: Init. failed for idmap_passdb ?!\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- if (!parse_idmap_module(idmap_alloc_ctx, backend, &modulename,
- &params)) {
- DEBUG(1, ("parse_idmap_module %s failed\n", backend));
- goto fail;
+ idmap_domains = talloc_realloc(idmap_ctx,
+ idmap_domains,
+ struct idmap_domain *,
+ num_domains+1);
+ if ( ! idmap_domains) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
}
+ idmap_domains[num_domains] = dom;
+
+ /* needed to handle special BUILTIN and wellknown SIDs cases */
+ pdb_dom_num = num_domains;
+
+ DEBUG(10, ("Domain %s - Backend passdb - not default - readonly\n",
+ dom->name));
+
+ num_domains++;
+ /**** finished adding idmap_passdb backend ****/
- idmap_alloc_ctx->methods = get_alloc_methods(modulename);
+ /* sort domains so that the default is the last one */
+ /* don't sort if no default domain defined */
+ if (def_dom_num != -1 && def_dom_num != num_domains-1) {
+ /* default is not last, move it */
+ struct idmap_domain *tmp;
- if (idmap_alloc_ctx->methods == NULL) {
- ret = smb_probe_module("idmap", modulename);
- if (NT_STATUS_IS_OK(ret)) {
- idmap_alloc_ctx->methods =
- get_alloc_methods(modulename);
+ if (pdb_dom_num > def_dom_num) {
+ pdb_dom_num --;
+
+ } else if (pdb_dom_num == def_dom_num) { /* ?? */
+ pdb_dom_num = num_domains - 1;
}
+
+ tmp = idmap_domains[def_dom_num];
+
+ for (i = def_dom_num; i < num_domains-1; i++) {
+ idmap_domains[i] = idmap_domains[i+1];
+ }
+ idmap_domains[i] = tmp;
+ def_dom_num = i;
}
- if (idmap_alloc_ctx->methods == NULL) {
- DEBUG(1, ("could not find idmap alloc module %s\n", backend));
- ret = NT_STATUS_INVALID_PARAMETER;
- goto fail;
+
+ /* Initialize alloc module */
+
+ DEBUG(3, ("Initializing idmap alloc module\n"));
+
+ alloc_backend = NULL;
+ if (compat) {
+ alloc_backend = talloc_strdup(idmap_ctx, compat_backend);
+ } else {
+ char *ab = lp_idmap_alloc_backend();
+
+ if (ab && (ab[0] != '\0')) {
+ alloc_backend = talloc_strdup(idmap_ctx,
+ lp_idmap_alloc_backend());
+ }
}
- ret = idmap_alloc_ctx->methods->init(params);
+ if ( alloc_backend ) {
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(0, ("ERROR: Initialization failed for alloc "
- "backend, deferred!\n"));
- goto fail;
+ idmap_alloc_ctx = TALLOC_ZERO_P(idmap_ctx,
+ struct idmap_alloc_context);
+ IDMAP_CHECK_ALLOC(idmap_alloc_ctx);
+
+ idmap_alloc_ctx->methods = get_alloc_methods(alloc_backend);
+ if ( ! idmap_alloc_ctx->methods) {
+ ret = smb_probe_module("idmap", alloc_backend);
+ if (NT_STATUS_IS_OK(ret)) {
+ idmap_alloc_ctx->methods =
+ get_alloc_methods(alloc_backend);
+ }
+ }
+ if (idmap_alloc_ctx->methods) {
+
+ if (compat_params) {
+ idmap_alloc_ctx->params =
+ talloc_strdup(idmap_alloc_ctx,
+ compat_params);
+ IDMAP_CHECK_ALLOC(idmap_alloc_ctx->params);
+ } else {
+ idmap_alloc_ctx->params = NULL;
+ }
+
+ ret = idmap_alloc_ctx->methods->init(idmap_alloc_ctx->params);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ DEBUG(0, ("ERROR: Initialization failed for "
+ "alloc backend %s, deferred!\n",
+ alloc_backend));
+ } else {
+ idmap_alloc_ctx->initialized = True;
+ }
+ } else {
+ DEBUG(2, ("idmap_init: Unable to get methods for "
+ "alloc backend %s\n",
+ alloc_backend));
+ /* certain compat backends are just readonly */
+ if ( compat ) {
+ TALLOC_FREE(idmap_alloc_ctx);
+ ret = NT_STATUS_OK;
+ } else {
+ ret = NT_STATUS_UNSUCCESSFUL;
+ }
+ }
}
- TALLOC_FREE(modulename);
- TALLOC_FREE(params);
+ /* cleanup temporary strings */
+ TALLOC_FREE( compat_backend );
- *ctx = idmap_alloc_ctx;
- return NT_STATUS_OK;
+ idmap_init_status = NT_STATUS_OK;
+
+ return ret;
+
+done:
+ DEBUG(0, ("Aborting IDMAP Initialization ...\n"));
+ idmap_close();
-fail:
- TALLOC_FREE(idmap_alloc_ctx);
return ret;
}
+static NTSTATUS idmap_alloc_init(void)
+{
+ NTSTATUS ret;
+
+ if (! NT_STATUS_IS_OK(ret = idmap_init())) {
+ return ret;
+ }
+
+ if ( ! idmap_alloc_ctx) {
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
+ if ( ! idmap_alloc_ctx->initialized) {
+ ret = idmap_alloc_ctx->methods->init(idmap_alloc_ctx->params);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ DEBUG(0, ("ERROR: Initialization failed for alloc "
+ "backend, deferred!\n"));
+ return ret;
+ } else {
+ idmap_alloc_ctx->initialized = True;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
/**************************************************************************
idmap allocator interface functions
**************************************************************************/
NTSTATUS idmap_allocate_uid(struct unixid *id)
{
- struct idmap_alloc_context *ctx;
NTSTATUS ret;
- if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {
+ if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) {
return ret;
}
id->type = ID_TYPE_UID;
- return ctx->methods->allocate_id(id);
+ return idmap_alloc_ctx->methods->allocate_id(id);
}
NTSTATUS idmap_allocate_gid(struct unixid *id)
{
- struct idmap_alloc_context *ctx;
NTSTATUS ret;
- if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {
+ if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) {
return ret;
}
id->type = ID_TYPE_GID;
- return ctx->methods->allocate_id(id);
+ return idmap_alloc_ctx->methods->allocate_id(id);
}
NTSTATUS idmap_set_uid_hwm(struct unixid *id)
{
- struct idmap_alloc_context *ctx;
NTSTATUS ret;
- if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {
+ if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) {
return ret;
}
id->type = ID_TYPE_UID;
- return ctx->methods->set_id_hwm(id);
+ return idmap_alloc_ctx->methods->set_id_hwm(id);
}
NTSTATUS idmap_set_gid_hwm(struct unixid *id)
{
- struct idmap_alloc_context *ctx;
NTSTATUS ret;
- if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {
+ if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) {
return ret;
}
id->type = ID_TYPE_GID;
- return ctx->methods->set_id_hwm(id);
+ return idmap_alloc_ctx->methods->set_id_hwm(id);
+}
+
+/******************************************************************************
+ Lookup an idmap_domain give a full user or group SID
+ ******************************************************************************/
+
+static struct idmap_domain* find_idmap_domain_from_sid( DOM_SID *account_sid )
+{
+ DOM_SID domain_sid;
+ uint32_t rid;
+ struct winbindd_domain *domain = NULL;
+ int i;
+
+ /* 1. Handle BUILTIN or Special SIDs and prevent them from
+ falling into the default domain space (if we have a
+ configured passdb backend. */
+
+ if ( (pdb_dom_num != -1) &&
+ (sid_check_is_in_builtin(account_sid) ||
+ sid_check_is_in_wellknown_domain(account_sid) ||
+ sid_check_is_in_unix_groups(account_sid) ||
+ sid_check_is_in_unix_users(account_sid)) )
+ {
+ return idmap_domains[pdb_dom_num];
+ }
+
+ /* 2. Lookup the winbindd_domain from the account_sid */
+
+ sid_copy( &domain_sid, account_sid );
+ sid_split_rid( &domain_sid, &rid );
+ domain = find_domain_from_sid_noinit( &domain_sid );
+
+ for (i = 0; domain && i < num_domains; i++) {
+ if ( strequal( idmap_domains[i]->name, domain->name ) ) {
+ return idmap_domains[i];
+ }
+ }
+
+ /* 3. Fall back to the default domain */
+
+ if ( def_dom_num != -1 ) {
+ return idmap_domains[def_dom_num];
+ }
+
+ return NULL;
}
-NTSTATUS idmap_new_mapping(const struct dom_sid *psid, enum id_type type,
- struct unixid *pxid)
+/******************************************************************************
+ Lookup an index given an idmap_domain pointer
+ ******************************************************************************/
+
+static uint32_t find_idmap_domain_index( struct idmap_domain *id_domain)
+{
+ int i;
+
+ for (i = 0; i < num_domains; i++) {
+ if ( idmap_domains[i] == id_domain )
+ return i;
+ }
+
+ return -1;
+}
+
+
+/*********************************************************
+ Check if creating a mapping is permitted for the domain
+*********************************************************/
+
+static NTSTATUS idmap_can_map(const struct id_map *map,
+ struct idmap_domain **ret_dom)
{
- struct dom_sid sid;
struct idmap_domain *dom;
- struct id_map map;
- NTSTATUS status;
- dom = idmap_find_domain(NULL);
- if (dom == NULL) {
- DEBUG(3, ("no default domain, no place to write\n"));
- return NT_STATUS_ACCESS_DENIED;
+ /* Check we do not create mappings for our own local domain,
+ * or BUILTIN or special SIDs */
+ if ((sid_compare_domain(map->sid, get_global_sam_sid()) == 0) ||
+ sid_check_is_in_builtin(map->sid) ||
+ sid_check_is_in_wellknown_domain(map->sid) ||
+ sid_check_is_in_unix_users(map->sid) ||
+ sid_check_is_in_unix_groups(map->sid) )
+ {
+ DEBUG(10, ("We are not supposed to create mappings for our own "
+ "domains (local, builtin, specials)\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Special check for trusted domain only = Yes */
+ if (lp_winbind_trusted_domains_only()) {
+ struct winbindd_domain *wdom = find_our_domain();
+ if (wdom && (sid_compare_domain(map->sid, &wdom->sid) == 0)) {
+ DEBUG(10, ("We are not supposed to create mappings for "
+ "our primary domain when <trusted domain "
+ "only> is True\n"));
+ DEBUGADD(10, ("Leave [%s] unmapped\n",
+ sid_string_dbg(map->sid)));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ if ( (dom = find_idmap_domain_from_sid( map->sid )) == NULL ) {
+ /* huh, couldn't find a suitable domain,
+ * let's just leave it unmapped */
+ DEBUG(10, ("Could not find idmap backend for SID %s\n",
+ sid_string_dbg(map->sid)));
+ return NT_STATUS_NO_SUCH_DOMAIN;
+ }
+
+ if (dom->readonly) {
+ /* ouch the domain is read only,
+ * let's just leave it unmapped */
+ DEBUG(10, ("idmap backend for SID %s is READONLY!\n",
+ sid_string_dbg(map->sid)));
+ return NT_STATUS_UNSUCCESSFUL;
}
- if (dom->methods->set_mapping == NULL) {
- DEBUG(3, ("default domain not writable\n"));
- return NT_STATUS_MEDIA_WRITE_PROTECTED;
+
+ *ret_dom = dom;
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS idmap_new_mapping(TALLOC_CTX *ctx, struct id_map *map)
+{
+ NTSTATUS ret;
+ struct idmap_domain *dom;
+
+ /* If we are offline we cannot lookup SIDs, deny mapping */
+ if (idmap_is_offline()) {
+ return NT_STATUS_FILE_IS_OFFLINE;
}
- sid_copy(&sid, psid);
- map.sid = &sid;
- map.xid.type = type;
+ ret = idmap_can_map(map, &dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return NT_STATUS_NONE_MAPPED;
+ }
- switch (type) {
+ /* check if this is a valid SID and then map it */
+ switch (map->xid.type) {
case ID_TYPE_UID:
- status = idmap_allocate_uid(&map.xid);
+ ret = idmap_allocate_uid(&map->xid);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ /* can't allocate id, let's just leave it unmapped */
+ DEBUG(2, ("uid allocation failed! "
+ "Can't create mapping\n"));
+ return NT_STATUS_NONE_MAPPED;
+ }
break;
case ID_TYPE_GID:
- status = idmap_allocate_gid(&map.xid);
+ ret = idmap_allocate_gid(&map->xid);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ /* can't allocate id, let's just leave it unmapped */
+ DEBUG(2, ("gid allocation failed! "
+ "Can't create mapping\n"));
+ return NT_STATUS_NONE_MAPPED;
+ }
break;
default:
- status = NT_STATUS_INVALID_PARAMETER;
- break;
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("Could not allocate id: %s\n", nt_errstr(status)));
- return status;
+ /* invalid sid, let's just leave it unmapped */
+ DEBUG(3,("idmap_new_mapping: Refusing to create a "
+ "mapping for an unspecified ID type.\n"));
+ return NT_STATUS_NONE_MAPPED;
}
- map.status = ID_MAPPED;
+ /* ok, got a new id, let's set a mapping */
+ map->status = ID_MAPPED;
DEBUG(10, ("Setting mapping: %s <-> %s %lu\n",
- sid_string_dbg(map.sid),
- (map.xid.type == ID_TYPE_UID) ? "UID" : "GID",
- (unsigned long)map.xid.id));
+ sid_string_dbg(map->sid),
+ (map->xid.type == ID_TYPE_UID) ? "UID" : "GID",
+ (unsigned long)map->xid.id));
+ ret = dom->methods->set_mapping(dom, map);
+
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ /* something wrong here :-( */
+ DEBUG(2, ("Failed to commit mapping\n!"));
- status = dom->methods->set_mapping(dom, &map);
+ /* TODO: would it make sense to have an "unalloc_id function?" */
- if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
- struct id_map *ids[2];
- DEBUG(5, ("Mapping for %s exists - retrying to map sid\n",
- sid_string_dbg(map.sid)));
- ids[0] = &map;
- ids[1] = NULL;
- status = dom->methods->sids_to_unixids(dom, ids);
+ return NT_STATUS_NONE_MAPPED;
}
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("Could not store the new mapping: %s\n",
- nt_errstr(status)));
- return status;
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS idmap_backends_set_mapping(const struct id_map *map)
+{
+ struct idmap_domain *dom;
+ NTSTATUS ret;
+
+ DEBUG(10, ("Setting mapping %s <-> %s %lu\n",
+ sid_string_dbg(map->sid),
+ (map->xid.type == ID_TYPE_UID) ? "UID" : "GID",
+ (unsigned long)map->xid.id));
+
+ ret = idmap_can_map(map, &dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
}
- *pxid = map.xid;
+ DEBUG(10,("set_mapping for domain %s\n", dom->name ));
- return NT_STATUS_OK;
+ return dom->methods->set_mapping(dom, map);
}
-NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id)
+static NTSTATUS idmap_backends_unixids_to_sids(struct id_map **ids)
{
struct idmap_domain *dom;
- struct id_map *maps[2];
+ struct id_map **unmapped;
+ struct id_map **_ids;
+ TALLOC_CTX *ctx;
+ NTSTATUS ret;
+ int i, u, n;
- maps[0] = id;
- maps[1] = NULL;
+ if (!ids || !*ids) {
+ DEBUG(1, ("Invalid list of maps\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- /*
- * Always give passdb a chance first
- */
+ ctx = talloc_named_const(NULL, 0, "idmap_backends_unixids_to_sids ctx");
+ if ( ! ctx) {
+ DEBUG(0, ("Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ DEBUG(10, ("Query backends to map ids->sids\n"));
+
+ /* start from the default (the last one) and then if there are still
+ * unmapped entries cycle through the others */
+
+ _ids = ids;
+
+ unmapped = NULL;
+ for (n = num_domains-1; n >= 0; n--) { /* cycle backwards */
+
+ dom = idmap_domains[n];
+
+ DEBUG(10, ("Query sids from domain %s\n", dom->name));
+
+ ret = dom->methods->unixids_to_sids(dom, _ids);
+ IDMAP_REPORT_RET(ret);
+
+ unmapped = NULL;
+
+ for (i = 0, u = 0; _ids[i]; i++) {
+ if (_ids[i]->status != ID_MAPPED) {
+ unmapped = talloc_realloc(ctx, unmapped,
+ struct id_map *, u + 2);
+ IDMAP_CHECK_ALLOC(unmapped);
+ unmapped[u] = _ids[i];
+ u++;
+ }
+ }
+ if (unmapped) {
+ /* terminate the unmapped list */
+ unmapped[u] = NULL;
+ } else { /* no more entries, get out */
+ break;
+ }
+
+ _ids = unmapped;
- dom = idmap_init_passdb_domain(NULL);
- if ((dom != NULL)
- && NT_STATUS_IS_OK(dom->methods->unixids_to_sids(dom, maps))) {
- return NT_STATUS_OK;
}
- dom = idmap_find_domain(domname);
- if (dom == NULL) {
- return NT_STATUS_NONE_MAPPED;
+ if (unmapped) {
+ /* there are still unmapped ids,
+ * map them to the unix users/groups domains */
+ /* except for expired entries,
+ * these will be returned as valid (offline mode) */
+ for (i = 0; unmapped[i]; i++) {
+ if (unmapped[i]->status == ID_EXPIRED) continue;
+ switch (unmapped[i]->xid.type) {
+ case ID_TYPE_UID:
+ uid_to_unix_users_sid(
+ (uid_t)unmapped[i]->xid.id,
+ unmapped[i]->sid);
+ unmapped[i]->status = ID_MAPPED;
+ break;
+ case ID_TYPE_GID:
+ gid_to_unix_groups_sid(
+ (gid_t)unmapped[i]->xid.id,
+ unmapped[i]->sid);
+ unmapped[i]->status = ID_MAPPED;
+ break;
+ default: /* what?! */
+ unmapped[i]->status = ID_UNKNOWN;
+ break;
+ }
+ }
}
- return dom->methods->unixids_to_sids(dom, maps);
+ ret = NT_STATUS_OK;
+
+done:
+ talloc_free(ctx);
+ return ret;
}
-NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id)
+static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids)
{
+ struct id_map ***dom_ids;
struct idmap_domain *dom;
- struct id_map *maps[2];
+ TALLOC_CTX *ctx;
+ NTSTATUS ret;
+ int i, *counters;
- maps[0] = id;
- maps[1] = NULL;
+ if ( (ctx = talloc_named_const(NULL, 0, "be_sids_to_ids")) == NULL ) {
+ DEBUG(1, ("failed to allocate talloc context, OOM?\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
- if (sid_check_is_in_builtin(id->sid)
- || (sid_check_is_in_our_domain(id->sid))) {
+ DEBUG(10, ("Query backends to map sids->ids\n"));
- dom = idmap_init_passdb_domain(NULL);
- if (dom == NULL) {
- return NT_STATUS_NONE_MAPPED;
+ /* split list per domain */
+ if (num_domains == 0) {
+ DEBUG(1, ("No domains available?\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ dom_ids = TALLOC_ZERO_ARRAY(ctx, struct id_map **, num_domains);
+ IDMAP_CHECK_ALLOC(dom_ids);
+ counters = TALLOC_ZERO_ARRAY(ctx, int, num_domains);
+ IDMAP_CHECK_ALLOC(counters);
+
+ /* partition the requests by domain */
+
+ for (i = 0; ids[i]; i++) {
+ uint32_t idx;
+
+ if ((dom = find_idmap_domain_from_sid(ids[i]->sid)) == NULL) {
+ /* no available idmap_domain. Move on */
+ continue;
}
- return dom->methods->sids_to_unixids(dom, maps);
+
+ DEBUG(10,("SID %s is being handled by %s\n",
+ sid_string_dbg(ids[i]->sid),
+ dom ? dom->name : "none" ));
+
+ idx = find_idmap_domain_index( dom );
+ SMB_ASSERT( idx != -1 );
+
+ dom_ids[idx] = talloc_realloc(ctx, dom_ids[idx],
+ struct id_map *,
+ counters[idx] + 2);
+ IDMAP_CHECK_ALLOC(dom_ids[idx]);
+
+ dom_ids[idx][counters[idx]] = ids[i];
+ counters[idx]++;
+ dom_ids[idx][counters[idx]] = NULL;
}
- dom = idmap_find_domain(domain);
- if (dom == NULL) {
- return NT_STATUS_NONE_MAPPED;
+ /* All the ids have been dispatched in the right queues.
+ Let's cycle through the filled ones */
+
+ for (i = 0; i < num_domains; i++) {
+ if (dom_ids[i]) {
+ dom = idmap_domains[i];
+ DEBUG(10, ("Query ids from domain %s\n", dom->name));
+ ret = dom->methods->sids_to_unixids(dom, dom_ids[i]);
+ IDMAP_REPORT_RET(ret);
+ }
+ }
+
+ /* ok all the backends have been contacted at this point */
+ /* let's see if we have any unmapped SID left and act accordingly */
+
+ for (i = 0; ids[i]; i++) {
+ /* NOTE: this will NOT touch ID_EXPIRED entries that the backend
+ * was not able to confirm/deny (offline mode) */
+ if (ids[i]->status == ID_UNKNOWN ||
+ ids[i]->status == ID_UNMAPPED) {
+ /* ok this is an unmapped one, see if we can map it */
+ ret = idmap_new_mapping(ctx, ids[i]);
+ if (NT_STATUS_IS_OK(ret)) {
+ /* successfully mapped */
+ ids[i]->status = ID_MAPPED;
+ } else
+ if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
+ /* could not map it */
+ ids[i]->status = ID_UNMAPPED;
+ } else {
+ /* Something very bad happened down there
+ * OR we are offline */
+ ids[i]->status = ID_UNKNOWN;
+ }
+ }
}
- return dom->methods->sids_to_unixids(dom, maps);
+ ret = NT_STATUS_OK;
+
+done:
+ talloc_free(ctx);
+ return ret;
}
-NTSTATUS idmap_set_mapping(const struct id_map *map)
+/**************************************************************************
+ idmap interface functions
+**************************************************************************/
+
+NTSTATUS idmap_unixids_to_sids(struct id_map **ids)
{
- struct idmap_domain *dom;
+ TALLOC_CTX *ctx;
+ NTSTATUS ret;
+ struct id_map **bids;
+ int i, bi;
+ int bn = 0;
+ struct winbindd_domain *our_domain = find_our_domain();
+
+ if (! NT_STATUS_IS_OK(ret = idmap_init())) {
+ return ret;
+ }
- dom = idmap_find_domain(NULL);
- if (dom == NULL) {
- DEBUG(3, ("no default domain, no place to write\n"));
- return NT_STATUS_ACCESS_DENIED;
+ if (!ids || !*ids) {
+ DEBUG(1, ("Invalid list of maps\n"));
+ return NT_STATUS_INVALID_PARAMETER;
}
- if (dom->methods->set_mapping == NULL) {
- DEBUG(3, ("default domain not writable\n"));
- return NT_STATUS_MEDIA_WRITE_PROTECTED;
+
+ ctx = talloc_named_const(NULL, 0, "idmap_unixids_to_sids ctx");
+ if ( ! ctx) {
+ DEBUG(1, ("failed to allocate talloc context, OOM?\n"));
+ return NT_STATUS_NO_MEMORY;
}
- return dom->methods->set_mapping(dom, map);
+ /* no ids to be asked to the backends by default */
+ bids = NULL;
+ bi = 0;
+
+ for (i = 0; ids[i]; i++) {
+
+ if ( ! ids[i]->sid) {
+ DEBUG(1, ("invalid null SID in id_map array"));
+ talloc_free(ctx);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ ret = idmap_cache_map_id(idmap_cache, ids[i]);
+
+ if ( ! NT_STATUS_IS_OK(ret)) {
+
+ if ( ! bids) {
+ /* 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"));
+ talloc_free(ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ bn = 10;
+ }
+
+ /* add this id to the ones to be retrieved
+ * from the backends */
+ bids[bi] = ids[i];
+ bi++;
+
+ /* check if we need to allocate new space
+ * on the rids array */
+ if (bi == bn) {
+ bn += 10;
+ bids = talloc_realloc(ctx, bids,
+ struct id_map *, bn);
+ if ( ! bids) {
+ DEBUG(1, ("Out of memory!\n"));
+ talloc_free(ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ /* make sure the last element is NULL */
+ bids[bi] = NULL;
+ }
+ }
+
+ /* let's see if there is any id mapping to be retieved
+ * from the backends */
+ if (bids) {
+ bool online;
+
+ /* Only do query if we are online */
+ online = !IS_DOMAIN_OFFLINE(our_domain);
+ if (online) {
+ ret = idmap_backends_unixids_to_sids(bids);
+ IDMAP_CHECK_RET(ret);
+ }
+
+ /* update the cache */
+ for (i = 0; i < bi; i++) {
+ if (bids[i]->status == ID_MAPPED) {
+ ret = idmap_cache_set(idmap_cache, bids[i]);
+ } else if (bids[i]->status == ID_EXPIRED) {
+ /* the cache returned an expired entry and the
+ * backend was not able to clear the situation
+ * (offline). This handles a previous
+ * NT_STATUS_SYNCHRONIZATION_REQUIRED
+ * for disconnected mode, */
+ bids[i]->status = ID_MAPPED;
+ } else if (bids[i]->status == ID_UNKNOWN) {
+ /* something bad here. We were not able to
+ * handle this for some reason, mark it as
+ * unmapped and hope next time things will
+ * settle down. */
+ bids[i]->status = ID_UNMAPPED;
+ } else if (online) { /* unmapped */
+ ret = idmap_cache_set_negative_id(idmap_cache,
+ bids[i]);
+ }
+ IDMAP_CHECK_RET(ret);
+ }
+ }
+
+ ret = NT_STATUS_OK;
+done:
+ talloc_free(ctx);
+ return ret;
+}
+
+NTSTATUS idmap_sids_to_unixids(struct id_map **ids)
+{
+ TALLOC_CTX *ctx;
+ NTSTATUS ret;
+ struct id_map **bids;
+ int i, bi;
+ int bn = 0;
+ struct winbindd_domain *our_domain = find_our_domain();
+
+ if (! NT_STATUS_IS_OK(ret = idmap_init())) {
+ return ret;
+ }
+
+ if (!ids || !*ids) {
+ DEBUG(1, ("Invalid list of maps\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ ctx = talloc_named_const(NULL, 0, "idmap_sids_to_unixids ctx");
+ if ( ! ctx) {
+ DEBUG(1, ("failed to allocate talloc context, OOM?\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* no ids to be asked to the backends by default */
+ bids = NULL;
+ bi = 0;
+
+ for (i = 0; ids[i]; i++) {
+
+ if ( ! ids[i]->sid) {
+ DEBUG(1, ("invalid null SID in id_map array\n"));
+ talloc_free(ctx);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ ret = idmap_cache_map_sid(idmap_cache, ids[i]);
+
+ if ( ! NT_STATUS_IS_OK(ret)) {
+
+ if ( ! bids) {
+ /* 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"));
+ talloc_free(ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ bn = 10;
+ }
+
+ /* add this id to the ones to be retrieved
+ * from the backends */
+ bids[bi] = ids[i];
+ bi++;
+
+ /* check if we need to allocate new space
+ * on the ids array */
+ if (bi == bn) {
+ bn += 10;
+ bids = talloc_realloc(ctx, bids,
+ struct id_map *, bn);
+ if ( ! bids) {
+ DEBUG(1, ("Out of memory!\n"));
+ talloc_free(ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ /* make sure the last element is NULL */
+ bids[bi] = NULL;
+ }
+ }
+
+ /* let's see if there is any id mapping to be retieved
+ * from the backends */
+ if (bids) {
+ bool online;
+
+ /* Only do query if we are online */
+ online = !IS_DOMAIN_OFFLINE(our_domain);
+ if (online) {
+ ret = idmap_backends_sids_to_unixids(bids);
+ IDMAP_CHECK_RET(ret);
+ }
+
+ /* update the cache */
+ for (i = 0; bids[i]; i++) {
+ if (bids[i]->status == ID_MAPPED) {
+ ret = idmap_cache_set(idmap_cache, bids[i]);
+ } else if (bids[i]->status == ID_EXPIRED) {
+ /* the cache returned an expired entry and the
+ * backend was not able to clear the situation
+ * (offline). This handles a previous
+ * NT_STATUS_SYNCHRONIZATION_REQUIRED
+ * for disconnected mode, */
+ bids[i]->status = ID_MAPPED;
+ } else if (bids[i]->status == ID_UNKNOWN) {
+ /* something bad here. We were not able to
+ * handle this for some reason, mark it as
+ * unmapped and hope next time things will
+ * settle down. */
+ bids[i]->status = ID_UNMAPPED;
+ } else if (online) { /* unmapped */
+ ret = idmap_cache_set_negative_sid(idmap_cache,
+ bids[i]);
+ }
+ IDMAP_CHECK_RET(ret);
+ }
+ }
+
+ ret = NT_STATUS_OK;
+done:
+ talloc_free(ctx);
+ return ret;
+}
+
+NTSTATUS idmap_set_mapping(const struct id_map *id)
+{
+ TALLOC_CTX *ctx;
+ NTSTATUS ret;
+
+ if (! NT_STATUS_IS_OK(ret = idmap_init())) {
+ return ret;
+ }
+
+ /* sanity checks */
+ if ((id->sid == NULL) || (id->status != ID_MAPPED)) {
+ DEBUG(1, ("NULL SID or unmapped entry\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* TODO: check uid/gid range ? */
+
+ ctx = talloc_named_const(NULL, 0, "idmap_set_mapping ctx");
+ if ( ! ctx) {
+ DEBUG(1, ("failed to allocate talloc context, OOM?\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* set the new mapping */
+ ret = idmap_backends_set_mapping(id);
+ IDMAP_CHECK_RET(ret);
+
+ /* set the mapping in the cache */
+ ret = idmap_cache_set(idmap_cache, id);
+ IDMAP_CHECK_RET(ret);
+
+done:
+ talloc_free(ctx);
+ return ret;
+}
+
+char *idmap_fetch_secret(const char *backend, bool alloc,
+ const char *domain, const char *identity)
+{
+ char *tmp, *ret;
+ int r;
+
+ if (alloc) {
+ r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend);
+ } else {
+ r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
+ }
+
+ if (r < 0)
+ return NULL;
+
+ strupper_m(tmp); /* make sure the key is case insensitive */
+ ret = secrets_fetch_generic(tmp, identity);
+
+ SAFE_FREE(tmp);
+
+ return ret;
}
+
diff --git a/source/winbindd/idmap_ad.c b/source/winbindd/idmap_ad.c
index 8144d876d4..a2c0dac9cd 100644
--- a/source/winbindd/idmap_ad.c
+++ b/source/winbindd/idmap_ad.c
@@ -160,8 +160,7 @@ static ADS_STRUCT *ad_idmap_cached_connection(void)
/************************************************************************
***********************************************************************/
-static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom,
- const char *params)
+static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom)
{
struct idmap_ad_context *ctx;
char *config_option;
@@ -207,6 +206,7 @@ static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom,
}
dom->private_data = ctx;
+ dom->initialized = True;
talloc_free(config_option);
@@ -277,6 +277,14 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map
return NT_STATUS_FILE_IS_OFFLINE;
}
+ /* Initilization my have been deferred because we were offline */
+ if ( ! dom->initialized) {
+ ret = idmap_ad_initialize(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
if ( (memctx = talloc_new(ctx)) == NULL ) {
@@ -488,6 +496,14 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map
return NT_STATUS_FILE_IS_OFFLINE;
}
+ /* Initilization my have been deferred because we were offline */
+ if ( ! dom->initialized) {
+ ret = idmap_ad_initialize(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
if ( (memctx = talloc_new(ctx)) == NULL ) {
@@ -818,159 +834,6 @@ done:
return nt_status;
}
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS nss_ad_map_to_alias(TALLOC_CTX *mem_ctx,
- const char *domain,
- const char *name,
- char **alias)
-{
- ADS_STRUCT *ads_internal = NULL;
- const char *attrs[] = {NULL, /* attr_uid */
- NULL };
- char *filter = NULL;
- LDAPMessage *msg = NULL;
- ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
- /* Check incoming parameters */
-
- if ( !domain || !name || !*alias) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- goto done;
- }
-
- /* Only do query if we are online */
-
- if (idmap_is_offline()) {
- nt_status = NT_STATUS_FILE_IS_OFFLINE;
- goto done;
- }
-
- ads_internal = ad_idmap_cached_connection();
-
- if (!ads_internal || !ad_schema) {
- nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
- goto done;
- }
-
- attrs[0] = ad_schema->posix_uid_attr;
-
- filter = talloc_asprintf(mem_ctx,
- "(sAMAccountName=%s)",
- name);
- if (!filter) {
- nt_status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- ads_status = ads_search_retry(ads_internal, &msg, filter, attrs);
- if (!ADS_ERR_OK(ads_status)) {
- nt_status = ads_ntstatus(ads_status);
- goto done;
- }
-
- *alias = ads_pull_string(ads_internal, mem_ctx, msg, ad_schema->posix_uid_attr );
-
- if (!*alias) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- if (filter) {
- talloc_destroy(filter);
- }
- if (msg) {
- ads_msgfree(ads_internal, msg);
- }
-
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS nss_ad_map_from_alias( TALLOC_CTX *mem_ctx,
- const char *domain,
- const char *alias,
- char **name )
-{
- ADS_STRUCT *ads_internal = NULL;
- const char *attrs[] = {"sAMAccountName",
- NULL };
- char *filter = NULL;
- LDAPMessage *msg = NULL;
- ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- char *username;
-
- /* Check incoming parameters */
-
- if ( !alias || !name) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- goto done;
- }
-
- /* Only do query if we are online */
-
- if (idmap_is_offline()) {
- nt_status = NT_STATUS_FILE_IS_OFFLINE;
- goto done;
- }
-
- ads_internal = ad_idmap_cached_connection();
-
- if (!ads_internal || !ad_schema) {
- nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
- goto done;
- }
-
- filter = talloc_asprintf(mem_ctx,
- "(%s=%s)",
- ad_schema->posix_uid_attr,
- alias);
- if (!filter) {
- nt_status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- ads_status = ads_search_retry(ads_internal, &msg, filter, attrs);
- if (!ADS_ERR_OK(ads_status)) {
- nt_status = ads_ntstatus(ads_status);
- goto done;
- }
-
- username = ads_pull_string(ads_internal, mem_ctx, msg,
- "sAMAccountName");
- if (!username) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- *name = talloc_asprintf(mem_ctx, "%s\\%s",
- lp_workgroup(),
- username);
- if (!*name) {
- nt_status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- if (filter) {
- talloc_destroy(filter);
- }
- if (msg) {
- ads_msgfree(ads_internal, msg);
- }
-
- return nt_status;
-}
-
-
/************************************************************************
***********************************************************************/
@@ -996,27 +859,21 @@ static struct idmap_methods ad_methods = {
function which sets the intended schema model to use */
static struct nss_info_methods nss_rfc2307_methods = {
- .init = nss_rfc2307_init,
- .get_nss_info = nss_ad_get_info,
- .map_to_alias = nss_ad_map_to_alias,
- .map_from_alias = nss_ad_map_from_alias,
- .close_fn = nss_ad_close
+ .init = nss_rfc2307_init,
+ .get_nss_info = nss_ad_get_info,
+ .close_fn = nss_ad_close
};
static struct nss_info_methods nss_sfu_methods = {
- .init = nss_sfu_init,
- .get_nss_info = nss_ad_get_info,
- .map_to_alias = nss_ad_map_to_alias,
- .map_from_alias = nss_ad_map_from_alias,
- .close_fn = nss_ad_close
+ .init = nss_sfu_init,
+ .get_nss_info = nss_ad_get_info,
+ .close_fn = nss_ad_close
};
static struct nss_info_methods nss_sfu20_methods = {
- .init = nss_sfu20_init,
- .get_nss_info = nss_ad_get_info,
- .map_to_alias = nss_ad_map_to_alias,
- .map_from_alias = nss_ad_map_from_alias,
- .close_fn = nss_ad_close
+ .init = nss_sfu20_init,
+ .get_nss_info = nss_ad_get_info,
+ .close_fn = nss_ad_close
};
diff --git a/source/winbindd/idmap_adex/cell_util.c b/source/winbindd/idmap_adex/cell_util.c
deleted file mode 100644
index f5c08a0454..0000000000
--- a/source/winbindd/idmap_adex/cell_util.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * idmap_adex: Support for AD Forests
- *
- * Copyright (C) Gerald (Jerry) Carter 2006-2008
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include "idmap_adex.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-/**********************************************************************
-**********************************************************************/
-
- char *find_attr_string(char **list, size_t num_lines, const char *substr)
-{
- int i;
- int cmplen = strlen(substr);
-
- for (i = 0; i < num_lines; i++) {
- /* make sure to avoid substring matches like uid
- and uidNumber */
- if ((StrnCaseCmp(list[i], substr, cmplen) == 0) &&
- (list[i][cmplen] == '=')) {
- /* Don't return an empty string */
- if (list[i][cmplen + 1] != '\0')
- return &(list[i][cmplen + 1]);
-
- return NULL;
- }
- }
-
- return NULL;
-}
-
-/**********************************************************************
-**********************************************************************/
-
- bool is_object_class(char **list, size_t num_lines, const char *substr)
-{
- int i;
-
- for (i = 0; i < num_lines; i++) {
- if (strequal(list[i], substr)) {
- return true;
- }
- }
-
- return false;
-}
-
-/**********************************************************************
- Find out about the cell (e.g. use2307Attrs, etc...)
-**********************************************************************/
-
- NTSTATUS cell_lookup_settings(struct likewise_cell * cell)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
- /* Parameter check */
-
- if (!cell) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Only supporting Forest-wide, schema based searches */
-
- cell_set_flags(cell, LWCELL_FLAG_USE_RFC2307_ATTRS);
- cell_set_flags(cell, LWCELL_FLAG_SEARCH_FOREST);
-
- cell->provider = &ccp_unified;
-
- nt_status = NT_STATUS_OK;
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(1,("LWI: Failed to obtain cell settings (%s)\n",
- nt_errstr(nt_status)));
- }
-
- return nt_status;
-}
-
-
-static NTSTATUS cell_lookup_forest(struct likewise_cell *c)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct gc_info *gc = NULL;
-
- if (!c) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if ((gc = TALLOC_ZERO_P(NULL, struct gc_info)) == NULL) {
- nt_status = NT_STATUS_NO_MEMORY;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Query the rootDSE for the forest root naming conect first.
- Check that the a GC server for the forest has not already
- been added */
-
- nt_status = gc_find_forest_root(gc, cell_dns_domain(c));
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- c->forest_name = talloc_strdup(c, gc->forest_name);
- BAIL_ON_PTR_ERROR(c->forest_name, nt_status);
-
-done:
- if (gc) {
- talloc_free(gc);
- }
-
- return nt_status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
- NTSTATUS cell_locate_membership(ADS_STRUCT * ads)
-{
- ADS_STATUS status;
- char *domain_dn = ads_build_dn(lp_realm());
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- DOM_SID sid;
- struct likewise_cell *cell = NULL;
-
- /* In the Likewise plugin, I had to support the concept of cells
- based on the machine's membership in an OU. However, now I'll
- just assume our membership in the forest cell */
-
- DEBUG(2, ("locate_cell_membership: Located membership "
- "in cell \"%s\"\n", domain_dn));
-
- if ((cell = cell_new()) == NULL) {
- nt_status = NT_STATUS_NO_MEMORY;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- status = ads_domain_sid(ads, &sid);
- if (!ADS_ERR_OK(status)) {
- DEBUG(3,("locate_cell_membership: Failed to find "
- "domain SID for %s\n", domain_dn));
- }
-
- /* save the SID and search base for our domain */
-
- cell_set_dns_domain(cell, lp_realm());
- cell_set_connection(cell, ads);
- cell_set_dn(cell, domain_dn);
- cell_set_domain_sid(cell, &sid);
-
- /* Now save our forest root */
-
- cell_lookup_forest(cell);
-
- /* Add the cell to the list */
-
- if (!cell_list_add(cell)) {
- nt_status = NT_STATUS_INSUFFICIENT_RESOURCES;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Done! */
- nt_status = NT_STATUS_OK;
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0,("LWI: Failed to locate cell membership (%s)\n",
- nt_errstr(nt_status)));
- }
-
- SAFE_FREE(domain_dn);
-
- return nt_status;
-}
-
-/*********************************************************************
- ********************************************************************/
-
- int min_id_value(void)
-{
- int id_val;
-
- id_val = lp_parm_int(-1, "lwidentity", "min_id_value", MIN_ID_VALUE);
-
- /* Still don't let it go below 50 */
-
- return MAX(50, id_val);
-}
-
-/********************************************************************
- *******************************************************************/
-
- char *cell_dn_to_dns(const char *dn)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- char *domain = NULL;
- char *dns_name = NULL;
- const char *tmp_dn;
- char *buffer = NULL;
- TALLOC_CTX *frame = talloc_stackframe();
-
- if (!dn || !*dn) {
- goto done;
- }
-
- tmp_dn = talloc_strdup(frame, dn);
- BAIL_ON_PTR_ERROR(tmp_dn, nt_status);
-
- while (next_token_talloc(frame, &tmp_dn, &buffer, ",")) {
-
- /* skip everything up the where DC=... begins */
- if (StrnCaseCmp(buffer, "DC=", 3) != 0)
- continue;
-
- if (!domain) {
- domain = talloc_strdup(frame, &buffer[3]);
- } else {
- domain = talloc_asprintf_append(domain, ".%s",
- &buffer[3]);
- }
- BAIL_ON_PTR_ERROR(domain, nt_status);
- }
-
- dns_name = SMB_STRDUP(domain);
- BAIL_ON_PTR_ERROR(dns_name, nt_status);
-
- nt_status = NT_STATUS_OK;
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "cell_dn_to_dns", 1);
-
- talloc_destroy(frame);
-
- return dns_name;
-}
-
-/*********************************************************************
- ********************************************************************/
-
- NTSTATUS get_sid_type(ADS_STRUCT *ads,
- LDAPMessage *msg,
- enum lsa_SidType *type)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- uint32_t atype;
-
- if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) {
- nt_status = NT_STATUS_INVALID_USER_BUFFER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- switch (atype &0xF0000000) {
- case ATYPE_SECURITY_GLOBAL_GROUP:
- *type = SID_NAME_DOM_GRP;
- break;
- case ATYPE_SECURITY_LOCAL_GROUP:
- *type = SID_NAME_ALIAS;
- break;
- case ATYPE_NORMAL_ACCOUNT:
- case ATYPE_WORKSTATION_TRUST:
- case ATYPE_INTERDOMAIN_TRUST:
- *type = SID_NAME_USER;
- break;
- default:
- *type = SID_NAME_USE_NONE;
- nt_status = NT_STATUS_INVALID_ACCOUNT_NAME;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- return nt_status;
-}
diff --git a/source/winbindd/idmap_adex/domain_util.c b/source/winbindd/idmap_adex/domain_util.c
deleted file mode 100644
index ab31ccef7a..0000000000
--- a/source/winbindd/idmap_adex/domain_util.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * idmap_adex: Domain search interface
- *
- * Copyright (C) Gerald (Jerry) Carter 2007-2008
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include "idmap_adex.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-struct dc_info {
- struct dc_info *prev, *next;
- char *dns_name;
- struct likewise_cell *domain_cell;
-};
-
-static struct dc_info *_dc_server_list = NULL;
-
-
-/**********************************************************************
- *********************************************************************/
-
-static struct dc_info *dc_list_head(void)
-{
- return _dc_server_list;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS dc_add_domain(const char *domain)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct dc_info *dc = NULL;
-
- /* Check for duplicates */
-
- dc = dc_list_head();
- while (dc) {
- if (strequal (dc->dns_name, domain))
- break;
- dc = dc->next;
- }
-
- if (dc) {
- DEBUG(10,("dc_add_domain: %s already in list\n", domain));
- return NT_STATUS_OK;
- }
-
- dc = TALLOC_ZERO_P(NULL, struct dc_info);
- BAIL_ON_PTR_ERROR(dc, nt_status);
-
- dc->dns_name = talloc_strdup(dc, domain);
- BAIL_ON_PTR_ERROR(dc->dns_name, nt_status);
-
- DLIST_ADD_END(_dc_server_list, dc, struct dc_info*);
-
- nt_status = NT_STATUS_OK;
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- talloc_destroy(dc);
- DEBUG(0,("LWI: Failed to add new DC connection for %s (%s)\n",
- domain, nt_errstr(nt_status)));
- }
-
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static void dc_server_list_destroy(void)
-{
- struct dc_info *dc = dc_list_head();
-
- while (dc) {
- struct dc_info *p = dc->next;
-
- cell_destroy(dc->domain_cell);
- talloc_destroy(dc);
-
- dc = p;
- }
-
- return;
-}
-
-
-/**********************************************************************
- *********************************************************************/
-
- NTSTATUS domain_init_list(void)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct winbindd_tdc_domain *domains = NULL;
- size_t num_domains = 0;
- int i;
-
- if (_dc_server_list != NULL) {
- dc_server_list_destroy();
- }
-
- /* Add our domain */
-
- nt_status = dc_add_domain(lp_realm());
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if (!wcache_tdc_fetch_list(&domains, &num_domains)) {
- nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Add all domains with an incoming trust path */
-
- for (i=0; i<num_domains; i++) {
- uint32_t flags = (NETR_TRUST_FLAG_INBOUND|NETR_TRUST_FLAG_IN_FOREST);
-
- /* We just require one of the flags to be set here */
-
- if (domains[i].trust_flags & flags) {
- nt_status = dc_add_domain(domains[i].dns_name);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(2,("LWI: Failed to initialize DC list (%s)\n",
- nt_errstr(nt_status)));
- }
-
- TALLOC_FREE(domains);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS dc_do_search(struct dc_info *dc,
- const char *search_base,
- int scope,
- const char *expr,
- const char **attrs,
- LDAPMessage ** msg)
-{
- ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
- status = cell_do_search(dc->domain_cell, search_base,
- scope, expr, attrs, msg);
- nt_status = ads_ntstatus(status);
-
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static struct dc_info *dc_find_domain(const char *dns_domain)
-{
- struct dc_info *dc = dc_list_head();
-
- if (!dc)
- return NULL;
-
- while (dc) {
- if (strequal(dc->dns_name, dns_domain)) {
- return dc;
- }
-
- dc = dc->next;
- }
-
- return NULL;
-}
-
-/**********************************************************************
- *********************************************************************/
-
- NTSTATUS dc_search_domains(struct likewise_cell **cell,
- LDAPMessage **msg,
- const char *dn,
- const DOM_SID *sid)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX *frame = talloc_stackframe();
- char *dns_domain;
- const char *attrs[] = { "*", NULL };
- struct dc_info *dc = NULL;
- const char *base = NULL;
-
- if (!dn || !*dn) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- dns_domain = cell_dn_to_dns(dn);
- BAIL_ON_PTR_ERROR(dns_domain, nt_status);
-
- if ((dc = dc_find_domain(dns_domain)) == NULL) {
- nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Reparse the cell settings for the domain if necessary */
-
- if (!dc->domain_cell) {
- char *base_dn;
-
- base_dn = ads_build_dn(dc->dns_name);
- BAIL_ON_PTR_ERROR(base_dn, nt_status);
-
- nt_status = cell_connect_dn(&dc->domain_cell, base_dn);
- SAFE_FREE(base_dn);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = cell_lookup_settings(dc->domain_cell);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* By definition this is already part of a larger
- forest-wide search scope */
-
- cell_set_flags(dc->domain_cell, LWCELL_FLAG_SEARCH_FOREST);
- }
-
- /* Check whether we are operating in non-schema or RFC2307
- mode */
-
- if (cell_flags(dc->domain_cell) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
- nt_status = dc_do_search(dc, dn, LDAP_SCOPE_BASE,
- "(objectclass=*)", attrs, msg);
- } else {
- const char *sid_str = NULL;
- char *filter = NULL;
-
- sid_str = sid_string_talloc(frame, sid);
- BAIL_ON_PTR_ERROR(sid_str, nt_status);
-
- filter = talloc_asprintf(frame, "(keywords=backLink=%s)",
- sid_str);
- BAIL_ON_PTR_ERROR(filter, nt_status);
-
- base = cell_search_base(dc->domain_cell);
- BAIL_ON_PTR_ERROR(base, nt_status);
-
- nt_status = dc_do_search(dc, base, LDAP_SCOPE_SUBTREE,
- filter, attrs, msg);
- }
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- *cell = dc->domain_cell;
-
-done:
- talloc_destroy(CONST_DISCARD(char*, base));
- talloc_destroy(frame);
-
- return nt_status;
-}
diff --git a/source/winbindd/idmap_adex/gc_util.c b/source/winbindd/idmap_adex/gc_util.c
deleted file mode 100644
index 87dd3c058d..0000000000
--- a/source/winbindd/idmap_adex/gc_util.c
+++ /dev/null
@@ -1,848 +0,0 @@
-/*
- * idmap_adex: Global Catalog search interface
- *
- * Copyright (C) Gerald (Jerry) Carter 2007-2008
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include "idmap_adex.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-static struct gc_info *_gc_server_list = NULL;
-
-
-/**********************************************************************
- *********************************************************************/
-
-static struct gc_info *gc_list_head(void)
-{
- return _gc_server_list;
-}
-
-/**********************************************************************
- Checks if either of the domains is a subdomain of the other
- *********************************************************************/
-
-static bool is_subdomain(const char* a, const char *b)
-{
- char *s;
- TALLOC_CTX *frame = talloc_stackframe();
- char *x, *y;
- bool ret = false;
-
- /* Trivial cases */
-
- if (!a && !b)
- return true;
-
- if (!a || !b)
- return false;
-
- /* Normalize the case */
-
- x = talloc_strdup(frame, a);
- y = talloc_strdup(frame, b);
- if (!x || !y) {
- ret = false;
- goto done;
- }
-
- strupper_m(x);
- strupper_m(y);
-
- /* Exact match */
-
- if (strcmp(x, y) == 0) {
- ret = true;
- goto done;
- }
-
- /* Check for trailing substrings */
-
- s = strstr_m(x, y);
- if (s && (strlen(s) == strlen(y))) {
- ret = true;
- goto done;
- }
-
- s = strstr_m(y, x);
- if (s && (strlen(s) == strlen(x))) {
- ret = true;
- goto done;
- }
-
-done:
- talloc_destroy(frame);
-
- return ret;
-}
-
-/**********************************************************************
- *********************************************************************/
-
- NTSTATUS gc_find_forest_root(struct gc_info *gc, const char *domain)
-{
- ADS_STRUCT *ads = NULL;
- ADS_STATUS ads_status;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct nbt_cldap_netlogon_5 cldap_reply;
- TALLOC_CTX *frame = talloc_stackframe();
-
- if (!gc || !domain) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- ZERO_STRUCT(cldap_reply);
-
- ads = ads_init(domain, NULL, NULL);
- BAIL_ON_PTR_ERROR(ads, nt_status);
-
- ads->auth.flags = ADS_AUTH_NO_BIND;
- ads_status = ads_connect(ads);
- if (!ADS_ERR_OK(ads_status)) {
- DEBUG(4, ("find_forest_root: ads_connect(%s) failed! (%s)\n",
- domain, ads_errstr(ads_status)));
- }
- nt_status = ads_ntstatus(ads_status);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if (!ads_cldap_netlogon_5(frame,
- ads->config.ldap_server_name,
- ads->config.realm,
- &cldap_reply))
- {
- DEBUG(4,("find_forest_root: Failed to get a CLDAP reply from %s!\n",
- ads->server.ldap_server));
- nt_status = NT_STATUS_IO_TIMEOUT;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- gc->forest_name = talloc_strdup(gc, cldap_reply.forest);
- BAIL_ON_PTR_ERROR(gc->forest_name, nt_status);
-
-done:
- if (ads) {
- ads_destroy(&ads);
- }
-
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS gc_add_forest(const char *domain)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct gc_info *gc = NULL;
- struct gc_info *find_gc = NULL;
- char *dn;
- ADS_STRUCT *ads = NULL;
- struct likewise_cell *primary_cell = NULL;
-
- primary_cell = cell_list_head();
- if (!primary_cell) {
- nt_status = NT_STATUS_INVALID_SERVER_STATE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Check for duplicates based on domain name first as this
- requires no connection */
-
- find_gc = gc_list_head();
- while (find_gc) {
- if (strequal (find_gc->forest_name, domain))
- break;
- find_gc = find_gc->next;
- }
-
- if (find_gc) {
- DEBUG(10,("gc_add_forest: %s already in list\n", find_gc->forest_name));
- return NT_STATUS_OK;
- }
-
- if ((gc = TALLOC_ZERO_P(NULL, struct gc_info)) == NULL) {
- nt_status = NT_STATUS_NO_MEMORY;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Query the rootDSE for the forest root naming conect first.
- Check that the a GC server for the forest has not already
- been added */
-
- nt_status = gc_find_forest_root(gc, domain);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- find_gc = gc_list_head();
- while (find_gc) {
- if (strequal (find_gc->forest_name, gc->forest_name))
- break;
- find_gc = find_gc->next;
- }
-
- if (find_gc) {
- DEBUG(10,("gc_add_forest: Forest %s already in list\n",
- find_gc->forest_name));
- return NT_STATUS_OK;
- }
-
- /* Not found, so add it here. Make sure we connect to
- a DC in _this_ domain and not the forest root. */
-
- dn = ads_build_dn(gc->forest_name);
- BAIL_ON_PTR_ERROR(dn, nt_status);
-
- gc->search_base = talloc_strdup(gc, dn);
- SAFE_FREE(dn);
- BAIL_ON_PTR_ERROR(gc->search_base, nt_status);
-
-#if 0
- /* Can't use cell_connect_dn() here as there is no way to
- specifiy the LWCELL_FLAG_GC_CELL flag setting for cell_connect() */
-
- nt_status = cell_connect_dn(&gc->forest_cell, gc->search_base);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-#else
-
- gc->forest_cell = cell_new();
- BAIL_ON_PTR_ERROR(gc->forest_cell, nt_status);
-
- /* Set the DNS domain, dn, etc ... and add it to the list */
-
- cell_set_dns_domain(gc->forest_cell, gc->forest_name);
- cell_set_dn(gc->forest_cell, gc->search_base);
- cell_set_flags(gc->forest_cell, LWCELL_FLAG_GC_CELL);
-#endif
-
- /* It is possible to belong to a non-forest cell and a
- non-provisioned forest (at our domain levele). In that
- case, we should just inherit the flags from our primary
- cell since the GC searches will match our own schema
- model. */
-
- if (strequal(primary_cell->forest_name, gc->forest_name)
- || is_subdomain(primary_cell->dns_domain, gc->forest_name))
- {
- cell_set_flags(gc->forest_cell, cell_flags(primary_cell));
- } else {
- /* outside of our domain */
-
- nt_status = cell_connect(gc->forest_cell);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = cell_lookup_settings(gc->forest_cell);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Drop the connection now that we have the settings */
-
- ads = cell_connection(gc->forest_cell);
- ads_destroy(&ads);
- cell_set_connection(gc->forest_cell, NULL);
- }
-
- DLIST_ADD_END(_gc_server_list, gc, struct gc_info*);
-
- DEBUG(10,("gc_add_forest: Added %s to Global Catalog list of servers\n",
- gc->forest_name));
-
- nt_status = NT_STATUS_OK;
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- talloc_destroy(gc);
- DEBUG(3,("LWI: Failed to add new GC connection for %s (%s)\n",
- domain, nt_errstr(nt_status)));
- }
-
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static void gc_server_list_destroy(void)
-{
- struct gc_info *gc = gc_list_head();
-
- while (gc) {
- struct gc_info *p = gc->next;
-
- cell_destroy(gc->forest_cell);
- talloc_destroy(gc);
-
- gc = p;
- }
-
- _gc_server_list = NULL;
-
- return;
-}
-
-/**********************************************************************
- Setup the initial list of forests and initial the forest cell
- settings for each. FIXME!!!
- *********************************************************************/
-
- NTSTATUS gc_init_list(void)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct winbindd_tdc_domain *domains = NULL;
- size_t num_domains = 0;
- int i;
-
- if (_gc_server_list != NULL) {
- gc_server_list_destroy();
- }
-
- if (!wcache_tdc_fetch_list(&domains, &num_domains)) {
- nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Find our forest first. Have to try all domains here starting
- with our own. gc_add_forest() filters duplicates */
-
- nt_status = gc_add_forest(lp_realm());
- WARN_ON_NTSTATUS_ERROR(nt_status);
-
- for (i=0; i<num_domains; i++) {
- uint32_t flags = (NETR_TRUST_FLAG_IN_FOREST);
-
- /* I think we should be able to break out of loop once
- we add a GC for our forest and not have to test every one.
- In fact, this entire loop is probably irrelevant since
- the GC location code should always find a GC given lp_realm().
- Will have to spend time testing before making the change.
- --jerry */
-
- if ((domains[i].trust_flags & flags) == flags) {
- nt_status = gc_add_forest(domains[i].dns_name);
- WARN_ON_NTSTATUS_ERROR(nt_status);
- /* Don't BAIL here since not every domain may
- have a GC server */
- }
- }
-
- /* Now add trusted forests. gc_add_forest() will filter out
- duplicates. Check everything with an incoming trust path
- that is not in our own forest. */
-
- for (i=0; i<num_domains; i++) {
- uint32_t flags = domains[i].trust_flags;
- uint32_t attribs = domains[i].trust_attribs;
-
- /* Skip non_AD domains */
-
- if (strlen(domains[i].dns_name) == 0) {
- continue;
- }
-
- /* Only add a GC for a forest outside of our own.
- Ignore QUARANTINED/EXTERNAL trusts */
-
- if ((flags & NETR_TRUST_FLAG_INBOUND)
- && !(flags & NETR_TRUST_FLAG_IN_FOREST)
- && (attribs & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE))
- {
- nt_status = gc_add_forest(domains[i].dns_name);
- WARN_ON_NTSTATUS_ERROR(nt_status);
- }
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(2,("LWI: Failed to initialized GC list (%s)\n",
- nt_errstr(nt_status)));
- }
-
- TALLOC_FREE(domains);
-
- return nt_status;
-}
-
-
-/**********************************************************************
- *********************************************************************/
-
- struct gc_info *gc_search_start(void)
-{
- NTSTATUS nt_status = NT_STATUS_OK;
- struct gc_info *gc = gc_list_head();
-
- if (!gc) {
- nt_status = gc_init_list();
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- gc = gc_list_head();
- }
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(2,("LWI: Failed to initialize GC list (%s)\n",
- nt_errstr(nt_status)));
- }
-
- return gc;
-}
-
-/**********************************************************************
- Search Global Catalog. Always search our own forest. The flags set
- controls whether or not we search cross forest. Assume that the
- resulting set is always returned from one GC so that we don't have to
- both combining the LDAPMessage * results
- *********************************************************************/
-
- NTSTATUS gc_search_forest(struct gc_info *gc,
- LDAPMessage **msg,
- const char *filter)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
- const char *attrs[] = {"*", NULL};
- LDAPMessage *m = NULL;
-
- if (!gc || !msg || !filter) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* When you have multiple domain trees in a forest, the
- GC will search all naming contexts when you send it
- and empty ("") base search suffix. Tested against
- Windows 2003. */
-
- ads_status = cell_do_search(gc->forest_cell, "",
- LDAP_SCOPE_SUBTREE, filter, attrs, &m);
- nt_status = ads_ntstatus(ads_status);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- *msg = m;
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(2,("LWI: Forest wide search %s failed (%s)\n",
- filter, nt_errstr(nt_status)));
- }
-
- return nt_status;
-}
-
-/**********************************************************************
- Search all forests via GC and return the results in an array of
- ADS_STRUCT/LDAPMessage pairs.
- *********************************************************************/
-
- NTSTATUS gc_search_all_forests(const char *filter,
- ADS_STRUCT ***ads_list,
- LDAPMessage ***msg_list,
- int *num_resp, uint32_t flags)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct gc_info *gc = NULL;
- uint32_t test_flags = ADEX_GC_SEARCH_CHECK_UNIQUE;
-
- *ads_list = NULL;
- *msg_list = NULL;
- *num_resp = 0;
-
- if ((gc = gc_search_start()) == NULL) {
- nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- while (gc) {
- LDAPMessage *m = NULL;
-
- nt_status = gc_search_forest(gc, &m, filter);
- if (!NT_STATUS_IS_OK(nt_status)) {
- gc = gc->next;
- continue;
- }
-
- nt_status = add_ads_result_to_array(cell_connection(gc->forest_cell),
- m, ads_list, msg_list,
- num_resp);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* If there can only be one match, then we are done */
-
- if ((*num_resp > 0) && ((flags & test_flags) == test_flags)) {
- break;
- }
-
- gc = gc->next;
- }
-
- if (*num_resp == 0) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- return nt_status;
-}
-
-/**********************************************************************
- Search all forests via GC and return the results in an array of
- ADS_STRUCT/LDAPMessage pairs.
- *********************************************************************/
-
- NTSTATUS gc_search_all_forests_unique(const char *filter,
- ADS_STRUCT **ads,
- LDAPMessage **msg)
-{
- ADS_STRUCT **ads_list = NULL;
- LDAPMessage **msg_list = NULL;
- int num_resp;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
- nt_status = gc_search_all_forests(filter, &ads_list,
- &msg_list, &num_resp,
- ADEX_GC_SEARCH_CHECK_UNIQUE);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = check_result_unique(ads_list[0], msg_list[0]);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- *ads = ads_list[0];
- *msg = msg_list[0];
-
-done:
- /* Be care that we don't free the msg result being returned */
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- free_result_array(ads_list, msg_list, num_resp);
- } else {
- talloc_destroy(ads_list);
- talloc_destroy(msg_list);
- }
-
- return nt_status;
-}
-
-/*********************************************************************
- ********************************************************************/
-
- NTSTATUS gc_name_to_sid(const char *domain,
- const char *name,
- DOM_SID *sid,
- enum lsa_SidType *sid_type)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- char *p, *name_user;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- char *name_filter;
- ADS_STRUCT *ads = NULL;
- LDAPMessage *msg = NULL;
- LDAPMessage *e = NULL;
- char *dn = NULL;
- char *dns_domain = NULL;
- ADS_STRUCT **ads_list = NULL;
- LDAPMessage **msg_list = NULL;
- int num_resp = 0;
- int i;
-
- /* Strip the "DOMAIN\" prefix if necessary and search for
- a matching sAMAccountName in the forest */
-
- if ((p = strchr_m( name, '\\' )) == NULL)
- name_user = talloc_strdup( frame, name );
- else
- name_user = talloc_strdup( frame, p+1 );
- BAIL_ON_PTR_ERROR(name_user, nt_status);
-
- name_filter = talloc_asprintf(frame, "(sAMAccountName=%s)", name_user);
- BAIL_ON_PTR_ERROR(name_filter, nt_status);
-
- nt_status = gc_search_all_forests(name_filter, &ads_list,
- &msg_list, &num_resp, 0);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Assume failure until we know otherwise*/
-
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-
- /* Match the domain name from the DN */
-
- for (i=0; i<num_resp; i++) {
- ads = ads_list[i];
- msg = msg_list[i];
-
- e = ads_first_entry(ads, msg);
- while (e) {
- struct winbindd_tdc_domain *domain_rec;
-
- dn = ads_get_dn(ads, e);
- BAIL_ON_PTR_ERROR(dn, nt_status);
-
- dns_domain = cell_dn_to_dns(dn);
- SAFE_FREE(dn);
- BAIL_ON_PTR_ERROR(dns_domain, nt_status);
-
- domain_rec = wcache_tdc_fetch_domain(frame, dns_domain);
- SAFE_FREE(dns_domain);
-
- /* Ignore failures and continue the search */
-
- if (!domain_rec) {
- e = ads_next_entry(ads, e);
- continue;
- }
-
- /* Check for a match on the domain name */
-
- if (strequal(domain, domain_rec->domain_name)) {
- if (!ads_pull_sid(ads, e, "objectSid", sid)) {
- nt_status = NT_STATUS_INVALID_SID;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- talloc_destroy(domain_rec);
-
- nt_status = get_sid_type(ads, msg, sid_type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* We're done! */
- nt_status = NT_STATUS_OK;
- break;
- }
-
- /* once more around thew merry-go-round */
-
- talloc_destroy(domain_rec);
- e = ads_next_entry(ads, e);
- }
- }
-
-done:
- free_result_array(ads_list, msg_list, num_resp);
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- Pull an attribute string value
- *******************************************************************/
-
-static NTSTATUS get_object_account_name(ADS_STRUCT *ads,
- LDAPMessage *msg,
- char **name)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- char *sam_name = NULL;
- struct winbindd_tdc_domain *domain_rec = NULL;
- char *dns_domain = NULL;
- char *dn = NULL;
- TALLOC_CTX *frame = talloc_stackframe();
- int len;
-
- /* Check parameters */
-
- if (!ads || !msg || !name) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* get the name and domain */
-
- dn = ads_get_dn(ads, msg);
- BAIL_ON_PTR_ERROR(dn, nt_status);
-
- DEBUG(10,("get_object_account_name: dn = \"%s\"\n", dn));
-
- dns_domain = cell_dn_to_dns(dn);
- SAFE_FREE(dn);
- BAIL_ON_PTR_ERROR(dns_domain, nt_status);
-
- domain_rec = wcache_tdc_fetch_domain(frame, dns_domain);
- SAFE_FREE(dns_domain);
-
- if (!domain_rec) {
- nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- sam_name = ads_pull_string(ads, frame, msg, "sAMAccountName");
- BAIL_ON_PTR_ERROR(sam_name, nt_status);
-
- len = asprintf(name, "%s\\%s", domain_rec->domain_name, sam_name);
- if (len == -1) {
- *name = NULL;
- BAIL_ON_PTR_ERROR((*name), nt_status);
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/*********************************************************************
- ********************************************************************/
-
- NTSTATUS gc_sid_to_name(const DOM_SID *sid,
- char **name,
- enum lsa_SidType *sid_type)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- char *filter;
- ADS_STRUCT *ads = NULL;
- LDAPMessage *msg = NULL;
- char *sid_string;
-
- *name = NULL;
-
- sid_string = sid_binstring(sid);
- BAIL_ON_PTR_ERROR(sid_string, nt_status);
-
- filter = talloc_asprintf(frame, "(objectSid=%s)", sid_string);
- SAFE_FREE(sid_string);
- BAIL_ON_PTR_ERROR(filter, nt_status);
-
- nt_status = gc_search_all_forests_unique(filter, &ads, &msg);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = get_object_account_name(ads, msg, name);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = get_sid_type(ads, msg, sid_type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- ads_msgfree(ads, msg);
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
- NTSTATUS add_ads_result_to_array(ADS_STRUCT *ads,
- LDAPMessage *msg,
- ADS_STRUCT ***ads_list,
- LDAPMessage ***msg_list,
- int *size)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- ADS_STRUCT **ads_tmp = NULL;
- LDAPMessage **msg_tmp = NULL;
- int count = *size;
-
- if (!ads || !msg) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
-#if 0
- /* Don't add a response with no entries */
-
- if (ads_count_replies(ads, msg) == 0) {
- return NT_STATUS_OK;
- }
-#endif
-
- if (count == 0) {
- ads_tmp = TALLOC_ARRAY(NULL, ADS_STRUCT*, 1);
- BAIL_ON_PTR_ERROR(ads_tmp, nt_status);
-
- msg_tmp = TALLOC_ARRAY(NULL, LDAPMessage*, 1);
- BAIL_ON_PTR_ERROR(msg_tmp, nt_status);
- } else {
- ads_tmp = TALLOC_REALLOC_ARRAY(*ads_list, *ads_list, ADS_STRUCT*,
- count+1);
- BAIL_ON_PTR_ERROR(ads_tmp, nt_status);
-
- msg_tmp = TALLOC_REALLOC_ARRAY(*msg_list, *msg_list, LDAPMessage*,
- count+1);
- BAIL_ON_PTR_ERROR(msg_tmp, nt_status);
- }
-
- ads_tmp[count] = ads;
- msg_tmp[count] = msg;
- count++;
-
- *ads_list = ads_tmp;
- *msg_list = msg_tmp;
- *size = count;
-
- nt_status = NT_STATUS_OK;
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- talloc_destroy(ads_tmp);
- talloc_destroy(msg_tmp);
- }
-
- return nt_status;
-}
-
-/**********************************************************************
- Frees search results. Do not free the ads_list as these are
- references back to the GC search structures.
- *********************************************************************/
-
- void free_result_array(ADS_STRUCT **ads_list,
- LDAPMessage **msg_list,
- int num_resp)
-{
- int i;
-
- for (i=0; i<num_resp; i++) {
- ads_msgfree(ads_list[i], msg_list[i]);
- }
-
- talloc_destroy(ads_list);
- talloc_destroy(msg_list);
-}
-
-/**********************************************************************
- Check that we have exactly one entry from the search
- *********************************************************************/
-
- NTSTATUS check_result_unique(ADS_STRUCT *ads, LDAPMessage *msg)
-{
- NTSTATUS nt_status;
- int count;
-
- count = ads_count_replies(ads, msg);
-
- if (count <= 0) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- if (count > 1) {
- nt_status = NT_STATUS_DUPLICATE_NAME;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- return nt_status;
-}
diff --git a/source/winbindd/idmap_adex/idmap_adex.c b/source/winbindd/idmap_adex/idmap_adex.c
deleted file mode 100644
index 23ab843e95..0000000000
--- a/source/winbindd/idmap_adex/idmap_adex.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * idmap_adex: Support for D Forests
- *
- * Copyright (C) Gerald (Jerry) Carter 2006-2008
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include "idmap_adex.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-#define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"
-
-NTSTATUS init_module(void);
-
-/*
- * IdMap backend
- */
-
-/********************************************************************
- Basic init function responsible for determining our current mode
- (standalone or using Centeris Cells). This must return success or
- it will be dropped from the idmap backend list.
- *******************************************************************/
-
-static NTSTATUS _idmap_adex_init(struct idmap_domain *dom,
- const char *params)
-{
- ADS_STRUCT *ads = NULL;
- ADS_STATUS status;
- static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- DOM_SID domain_sid;
- fstring dcname;
- struct sockaddr_storage ip;
- struct likewise_cell *lwcell;
-
- if (NT_STATUS_IS_OK(init_status))
- return NT_STATUS_OK;
-
- /* Silently fail if we are not a member server in security = ads */
-
- if ((lp_server_role() != ROLE_DOMAIN_MEMBER) ||
- (lp_security() != SEC_ADS)) {
- init_status = NT_STATUS_INVALID_SERVER_STATE;
- BAIL_ON_NTSTATUS_ERROR(init_status);
- }
-
- /* fetch our domain SID first */
-
- if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
- init_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- BAIL_ON_NTSTATUS_ERROR(init_status);
- }
-
- /* reuse the same ticket cache as winbindd */
-
- setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
-
- /* Establish a connection to a DC */
-
- if ((ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL) {
- init_status = NT_STATUS_NO_MEMORY;
- BAIL_ON_NTSTATUS_ERROR(init_status);
- }
-
- ads->auth.password =
- secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
- ads->auth.realm = SMB_STRDUP(lp_realm());
-
- /* get the DC name here to setup the server affinity cache and
- local krb5.conf */
-
- get_dc_name(lp_workgroup(), lp_realm(), dcname, &ip);
-
- status = ads_connect(ads);
- if (!ADS_ERR_OK(status)) {
- DEBUG(0, ("_idmap_adex_init: ads_connect() failed! (%s)\n",
- ads_errstr(status)));
- }
- init_status = ads_ntstatus(status);
- BAIL_ON_NTSTATUS_ERROR(init_status);
-
-
- /* Find out cell membership */
-
- init_status = cell_locate_membership(ads);
- if (!NT_STATUS_IS_OK(init_status)) {
- DEBUG(0,("LWI: Fail to locate cell membership (%s).",
- nt_errstr(init_status)));
- goto done;
- }
-
- /* Fill in the cell information */
-
- lwcell = cell_list_head();
-
- init_status = cell_lookup_settings(lwcell);
- BAIL_ON_NTSTATUS_ERROR(init_status);
-
- /* Miscellaneous setup. E.g. set up the list of GC
- servers and domain list for our forest (does not actually
- connect). */
-
- init_status = gc_init_list();
- BAIL_ON_NTSTATUS_ERROR(init_status);
-
- init_status = domain_init_list();
- BAIL_ON_NTSTATUS_ERROR(init_status);
-
-done:
- if (!NT_STATUS_IS_OK(init_status)) {
- DEBUG(1,("Likewise initialization failed (%s)\n",
- nt_errstr(init_status)));
- }
-
- /* cleanup */
-
- if (!NT_STATUS_IS_OK(init_status)) {
- cell_list_destroy();
-
- /* init_status stores the failure reason but we need to
- return success or else idmap_init() will drop us from the
- backend list */
- return NT_STATUS_OK;
- }
-
- init_status = NT_STATUS_OK;
-
- return init_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _idmap_adex_get_sid_from_id(struct
- idmap_domain
- *dom, struct
- id_map
- **ids)
-{
- int i;
- bool one_mapped = false;
- bool all_mapped = true;
- NTSTATUS nt_status;
- struct likewise_cell *cell;
-
- nt_status = _idmap_adex_init(dom, NULL);
- if (!NT_STATUS_IS_OK(nt_status))
- return nt_status;
-
- if ((cell = cell_list_head()) == NULL) {
- return NT_STATUS_INVALID_SERVER_STATE;
- }
-
- /* have to work through these one by one */
- for (i = 0; ids[i]; i++) {
- NTSTATUS status;
- status = cell->provider->get_sid_from_id(ids[i]->sid,
- ids[i]->xid.id,
- ids[i]->xid.type);
- /* Fail if we cannot find any DC */
- if (NT_STATUS_EQUAL
- (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- return status;
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- ids[i]->status = ID_UNMAPPED;
- all_mapped = false;
- continue;
- }
-
- ids[i]->status = ID_MAPPED;
- one_mapped = true;
- }
-
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _idmap_adex_get_id_from_sid(struct
- idmap_domain
- *dom, struct
- id_map
- **ids)
-{
- int i;
- bool one_mapped = false;
- bool all_mapped = true;
- NTSTATUS nt_status;
- struct likewise_cell *cell;
-
- nt_status = _idmap_adex_init(dom, NULL);
- if (!NT_STATUS_IS_OK(nt_status))
- return nt_status;
-
- if ((cell = cell_list_head()) == NULL) {
- return NT_STATUS_INVALID_SERVER_STATE;
- }
-
- /* have to work through these one by one */
- for (i = 0; ids[i]; i++) {
- NTSTATUS status;
- status = cell->provider->get_id_from_sid(&ids[i]->xid.id,
- &ids[i]->xid.
- type, ids[i]->sid);
- /* Fail if we cannot find any DC */
- if (NT_STATUS_EQUAL
- (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- return status;
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- ids[i]->status = ID_UNMAPPED;
- all_mapped = false;
- continue;
- }
-
- ids[i]->status = ID_MAPPED;
- one_mapped = true;
- }
-
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _idmap_adex_set_mapping(struct
- idmap_domain
- *dom, const struct
- id_map *map)
-{
- DEBUG(0, ("_idmap_adex_set_mapping: not implemented\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _idmap_adex_remove_mapping(struct
- idmap_domain
- *dom, const
- struct
- id_map
- *map)
-{
- DEBUG(0, ("_idmap_adex_remove_mapping: not implemented\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _idmap_adex_dump(struct idmap_domain
- *dom, struct id_map **maps, int *num_map)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _idmap_adex_close(struct idmap_domain
- *dom)
-{
- /* FIXME! need to do cleanup here */
-
- return NT_STATUS_OK;
-}
-
-/*
- * IdMap NSS plugin
- */
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _nss_adex_init(struct nss_domain_entry
- *e)
-{
- return _idmap_adex_init(NULL, NULL);
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _nss_adex_get_info(struct
- nss_domain_entry *e,
- const DOM_SID * sid,
- TALLOC_CTX * ctx,
- ADS_STRUCT * ads,
- LDAPMessage * msg,
- char **homedir,
- char **shell, char **gecos, gid_t * p_gid)
-{
- NTSTATUS nt_status;
- struct likewise_cell *cell;
-
- nt_status = _idmap_adex_init(NULL, NULL);
- if (!NT_STATUS_IS_OK(nt_status))
- return nt_status;
-
- if ((cell = cell_list_head()) == NULL) {
- return NT_STATUS_INVALID_SERVER_STATE;
- }
-
- return cell->provider->get_nss_info(sid, ctx, homedir,
- shell, gecos, p_gid);
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx, const char
- *domain, const char
- *name, char **alias)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct likewise_cell *cell = NULL;
-
- nt_status = _idmap_adex_init(NULL, NULL);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if ((cell = cell_list_head()) == NULL) {
- nt_status = NT_STATUS_INVALID_SERVER_STATE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- nt_status = cell->provider->map_to_alias(mem_ctx, domain,
- name, alias);
-
- /* go ahead and allow the cache mgr to mark this in
- negative cache */
-
- if (!NT_STATUS_IS_OK(nt_status))
- nt_status = NT_STATUS_NONE_MAPPED;
-
-done:
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx, const char
- *domain, const char
- *alias, char **name)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct likewise_cell *cell = NULL;
-
- nt_status = _idmap_adex_init(NULL, NULL);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if ((cell = cell_list_head()) == NULL) {
- nt_status = NT_STATUS_INVALID_SERVER_STATE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
-
- nt_status = cell->provider->map_from_alias(mem_ctx, domain,
- alias, name);
-
- /* go ahead and allow the cache mgr to mark this in
- negative cache */
-
- if (!NT_STATUS_IS_OK(nt_status))
- nt_status = NT_STATUS_NONE_MAPPED;
-
-done:
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _nss_adex_close(void)
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static struct idmap_methods adex_idmap_methods = {
-
- .init = _idmap_adex_init,
- .unixids_to_sids = _idmap_adex_get_sid_from_id,
- .sids_to_unixids = _idmap_adex_get_id_from_sid,
- .set_mapping = _idmap_adex_set_mapping,
- .remove_mapping = _idmap_adex_remove_mapping,
- .dump_data = _idmap_adex_dump,
- .close_fn = _idmap_adex_close
-};
-static struct nss_info_methods adex_nss_methods = {
- .init = _nss_adex_init,
- .get_nss_info = _nss_adex_get_info,
- .map_to_alias = _nss_adex_map_to_alias,
- .map_from_alias = _nss_adex_map_from_alias,
- .close_fn = _nss_adex_close
-};
-
-/**********************************************************************
- Register with the idmap and idmap_nss subsystems. We have to protect
- against the idmap and nss_info interfaces being in a half-registered
- state.
- **********************************************************************/
-NTSTATUS idmap_adex_init(void)
-{
- static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL;
- static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL;
- if (!NT_STATUS_IS_OK(idmap_status)) {
- idmap_status =
- smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
- "adex", &adex_idmap_methods);
- if (!NT_STATUS_IS_OK(idmap_status)) {
- DEBUG(0,
- ("idmap_centeris_init: Failed to register the adex"
- "idmap plugin.\n"));
- return idmap_status;
- }
- }
-
- if (!NT_STATUS_IS_OK(nss_status)) {
- nss_status =
- smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
- "adex", &adex_nss_methods);
- if (!NT_STATUS_IS_OK(nss_status)) {
- DEBUG(0,
- ("idmap_adex_init: Failed to register the adex"
- "nss plugin.\n"));
- return nss_status;
- }
- }
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS nss_info_adex_init(void)
-{
- return idmap_adex_init();
-}
diff --git a/source/winbindd/idmap_adex/idmap_adex.h b/source/winbindd/idmap_adex/idmap_adex.h
deleted file mode 100644
index f91bba8d07..0000000000
--- a/source/winbindd/idmap_adex/idmap_adex.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * idmap_centeris: Support for Local IDs and Centeris Cell Structure
- *
- * Copyright (C) Gerald (Jerry) Carter 2006-2008
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _IDMAP_ADEX_H
-#define _IDMAP_ADEX_H
-
-#include "winbindd/winbindd.h"
-
-#define ADEX_CELL_RDN "$LikewiseIdentityCell"
-
-#define ADEX_OC_USER "centerisLikewiseUser"
-#define ADEX_OC_GROUP "centerisLikewiseGroup"
-
-#define AD_USER "User"
-#define AD_GROUP "Group"
-
-#define ADEX_OC_POSIX_USER "posixAccount"
-#define ADEX_OC_POSIX_GROUP "posixGroup"
-
-#define ADEX_ATTR_UIDNUM "uidNumber"
-#define ADEX_ATTR_GIDNUM "gidNUmber"
-#define ADEX_ATTR_HOMEDIR "unixHomeDirectory"
-#define ADEX_ATTR_USERPW "unixUserPassword"
-#define ADEX_ATTR_GROUPALIAS "groupAlias" /* Not part of RFC2307 */
-#define ADEX_ATTR_SHELL "loginShell"
-#define ADEX_ATTR_GECOS "gecos"
-#define ADEX_ATTR_UID "uid"
-#define ADEX_ATTR_DISPLAYNAME "displayName"
-
-#define MIN_ID_VALUE 100
-
-#define BAIL_ON_NTSTATUS_ERROR(x) \
- do { \
- if (!NT_STATUS_IS_OK(x)) { \
- DEBUG(10,("Failed! (%s)\n", nt_errstr(x))); \
- goto done; \
- } \
- } \
- while (0); \
-
-#define WARN_ON_NTSTATUS_ERROR(x) \
- do { \
- if (!NT_STATUS_IS_OK(x)) { \
- DEBUG(10,("Failure ignored! (%s)\n", nt_errstr(x))); \
- } \
- } \
- while (0); \
-
-#define BAIL_ON_ADS_ERROR(x) \
- do { \
- if (!ADS_ERR_OK(x)) { \
- goto done; \
- } \
- } \
- while (0);
-
-#define BAIL_ON_PTR_ERROR(p, x) \
- do { \
- if ((p) == NULL ) { \
- DEBUG(10,("NULL pointer!\n")); \
- x = NT_STATUS_NO_MEMORY; \
- goto done; \
- } \
- } while (0);
-
-#define PRINT_NTSTATUS_ERROR(x, hdr, level) \
- do { \
- if (!NT_STATUS_IS_OK(x)) { \
- DEBUG(level,("LWI ("hdr"): %s\n", nt_errstr(x))); \
- } \
- } while(0);
-/*
- * Cell Provider API
- */
-
-struct cell_provider_api {
- NTSTATUS(*get_sid_from_id) (DOM_SID * sid,
- uint32_t id, enum id_type type);
- NTSTATUS(*get_id_from_sid) (uint32_t * id,
- enum id_type * type, const DOM_SID * sid);
- NTSTATUS(*get_nss_info) (const DOM_SID * sid,
- TALLOC_CTX * ctx,
- char **homedir,
- char **shell, char **gecos, gid_t * p_gid);
- NTSTATUS(*map_to_alias) (TALLOC_CTX * mem_ctx,
- const char *domain,
- const char *name, char **alias);
- NTSTATUS(*map_from_alias) (TALLOC_CTX * mem_ctx,
- const char *domain,
- const char *alias, char **name);
-};
-
-/* registered providers */
-
-extern struct cell_provider_api ccp_unified;
-extern struct cell_provider_api ccp_local;
-
-#define LWCELL_FLAG_USE_RFC2307_ATTRS 0x00000001
-#define LWCELL_FLAG_SEARCH_FOREST 0x00000002
-#define LWCELL_FLAG_GC_CELL 0x00000004
-#define LWCELL_FLAG_LOCAL_MODE 0x00000008
-
-struct likewise_cell {
- struct likewise_cell *prev, *next;
- ADS_STRUCT *conn;
- struct likewise_cell *gc_search_cell;
- DOM_SID domain_sid;
- char *dns_domain;
- char *forest_name;
- char *dn;
- struct GUID *links; /* only held by owning cell */
- size_t num_links;
- uint32_t flags;
- struct cell_provider_api *provider;
-};
-
-/* Search flags used for Global Catalog API */
-
-#define ADEX_GC_SEARCH_CHECK_UNIQUE 0x00000001
-
-struct gc_info {
- struct gc_info *prev, *next;
- char *forest_name;
- char *search_base;
- struct likewise_cell *forest_cell;
-};
-
-/* Available functions outside of idmap_lwidentity.c */
-
-/* cell_util.c */
-
-char *find_attr_string(char **list, size_t num_lines, const char *substr);
-bool is_object_class(char **list, size_t num_lines, const char *substr);
-int min_id_value(void);
-char *cell_dn_to_dns(const char *dn);
-NTSTATUS get_sid_type(ADS_STRUCT *ads,
- LDAPMessage *msg,
- enum lsa_SidType *type);
-
-NTSTATUS cell_locate_membership(ADS_STRUCT * ads);
-NTSTATUS cell_lookup_settings(struct likewise_cell * cell);
-NTSTATUS cell_follow_links(struct likewise_cell *cell);
-NTSTATUS cell_set_local_provider(void);
-
-/* likewise_cell.c */
-
-struct likewise_cell *cell_new(void);
-struct likewise_cell *cell_list_head(void);
-
-bool cell_list_add(struct likewise_cell *cell);
-bool cell_list_remove(struct likewise_cell * cell);
-
-void cell_list_destroy();
-void cell_destroy(struct likewise_cell *c);
-void cell_set_forest_searches(struct likewise_cell *c,
- bool search);
-void cell_set_dns_domain(struct likewise_cell *c,
- const char *dns_domain);
-void cell_set_connection(struct likewise_cell *c,
- ADS_STRUCT *ads);
-void cell_set_dn(struct likewise_cell *c,
- const char *dn);
-void cell_set_domain_sid(struct likewise_cell *c,
- DOM_SID *sid);
-void cell_set_flags(struct likewise_cell *c, uint32_t flags);
-void cell_clear_flags(struct likewise_cell *c, uint32_t flags);
-
-const char* cell_search_base(struct likewise_cell *c);
-const char *cell_dns_domain(struct likewise_cell *c);
-ADS_STRUCT *cell_connection(struct likewise_cell *c);
-bool cell_search_forest(struct likewise_cell *c);
-ADS_STATUS cell_do_search(struct likewise_cell *c,
- const char *search_base,
- int scope,
- const char *expr,
- const char **attrs,
- LDAPMessage ** msg);
-uint32_t cell_flags(struct likewise_cell *c);
-
-NTSTATUS cell_connect_dn(struct likewise_cell **c,
- const char *dn);
-NTSTATUS cell_connect(struct likewise_cell *c);
-
-
-/* gc_util.c */
-
-NTSTATUS gc_init_list(void);
-
-NTSTATUS gc_find_forest_root(struct gc_info *gc,
- const char *domain);
-
-struct gc_info *gc_search_start(void);
-
-NTSTATUS gc_search_forest(struct gc_info *gc,
- LDAPMessage **msg,
- const char *filter);
-
-NTSTATUS gc_search_all_forests(const char *filter,
- ADS_STRUCT ***ads_list,
- LDAPMessage ***msg_list,
- int *num_resp, uint32_t flags);
-
-NTSTATUS gc_search_all_forests_unique(const char *filter,
- ADS_STRUCT **ads,
- LDAPMessage **msg);
-
-NTSTATUS gc_name_to_sid(const char *domain,
- const char *name,
- DOM_SID *sid,
- enum lsa_SidType *sid_type);
-
-NTSTATUS gc_sid_to_name(const DOM_SID *sid,
- char **name,
- enum lsa_SidType *sid_type);
-
-NTSTATUS add_ads_result_to_array(ADS_STRUCT *ads,
- LDAPMessage *msg,
- ADS_STRUCT ***ads_list,
- LDAPMessage ***msg_list,
- int *size);
-
-void free_result_array(ADS_STRUCT **ads_list,
- LDAPMessage **msg_list,
- int num_resp);
-
-NTSTATUS check_result_unique(ADS_STRUCT *ads,
- LDAPMessage *msg);
-
-
-/* domain_util.c */
-
-NTSTATUS domain_init_list(void);
-
-NTSTATUS dc_search_domains(struct likewise_cell **cell,
- LDAPMessage **msg,
- const char *dn,
- const DOM_SID *user_sid);
-
-
-#endif /* _IDMAP_ADEX_H */
diff --git a/source/winbindd/idmap_adex/likewise_cell.c b/source/winbindd/idmap_adex/likewise_cell.c
deleted file mode 100644
index 77eeee406b..0000000000
--- a/source/winbindd/idmap_adex/likewise_cell.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * idmap_adex: Support for AD Forests
- *
- * Copyright (C) Gerald (Jerry) Carter 2006-2008
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include "idmap_adex.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-static struct likewise_cell *_lw_cell_list = NULL;
-
-/**********************************************************************
- Return the current HEAD of the list
- *********************************************************************/
-
- struct likewise_cell *cell_list_head(void)
-{
- return _lw_cell_list;
-}
-
-
-/**********************************************************************
- *********************************************************************/
-
- void cell_destroy(struct likewise_cell *c)
-{
- if (!c)
- return;
-
- if (c->conn)
- ads_destroy(&c->conn);
-
- talloc_destroy(c);
-}
-
-/**********************************************************************
- Free all cell entries and reset the list head to NULL
- *********************************************************************/
-
- void cell_list_destroy(void)
-{
- struct likewise_cell *p = _lw_cell_list;
-
- while (p) {
- struct likewise_cell *q = p->next;
-
- cell_destroy(p);
-
- p = q;
- }
-
- _lw_cell_list = NULL;
-
- return;
-}
-
-/**********************************************************************
- Add a new cell structure to the list
- *********************************************************************/
-
- struct likewise_cell* cell_new(void)
-{
- struct likewise_cell *c;
-
- /* Each cell struct is a TALLOC_CTX* */
-
- c = TALLOC_ZERO_P(NULL, struct likewise_cell);
- if (!c) {
- DEBUG(0,("cell_new: memory allocation failure!\n"));
- return NULL;
- }
-
- return c;
-}
-
-/**********************************************************************
- Add a new cell structure to the list
- *********************************************************************/
-
- bool cell_list_add(struct likewise_cell * cell)
-{
- if (!cell) {
- return false;
- }
-
- /* Always add to the end */
-
- DLIST_ADD_END(_lw_cell_list, cell, struct likewise_cell *);
-
- return true;
-}
-
-/**********************************************************************
- Add a new cell structure to the list
- *********************************************************************/
-
- bool cell_list_remove(struct likewise_cell * cell)
-{
- if (!cell) {
- return false;
- }
-
- /* Remove and drop the cell structure */
-
- DLIST_REMOVE(_lw_cell_list, cell);
- talloc_destroy(cell);
-
- return true;
-}
-
-/**********************************************************************
- Set the containing DNS domain for a cell
- *********************************************************************/
-
- void cell_set_dns_domain(struct likewise_cell *c, const char *dns_domain)
-{
- c->dns_domain = talloc_strdup(c, dns_domain);
-}
-
-/**********************************************************************
- Set ADS connection for a cell
- *********************************************************************/
-
- void cell_set_connection(struct likewise_cell *c, ADS_STRUCT *ads)
-{
- c->conn = ads;
-}
-
-/**********************************************************************
- *********************************************************************/
-
- void cell_set_flags(struct likewise_cell *c, uint32_t flags)
-{
- c->flags |= flags;
-}
-
-/**********************************************************************
- *********************************************************************/
-
- void cell_clear_flags(struct likewise_cell *c, uint32_t flags)
-{
- c->flags &= ~flags;
-}
-
-/**********************************************************************
- Set the Cell's DN
- *********************************************************************/
-
- void cell_set_dn(struct likewise_cell *c, const char *dn)
-{
- if ( c->dn) {
- talloc_free(c->dn);
- c->dn = NULL;
- }
-
- c->dn = talloc_strdup(c, dn);
-}
-
-/**********************************************************************
- *********************************************************************/
-
- void cell_set_domain_sid(struct likewise_cell *c, DOM_SID *sid)
-{
- sid_copy(&c->domain_sid, sid);
-}
-
-/*
- * Query Routines
- */
-
-/**********************************************************************
- *********************************************************************/
-
- const char* cell_search_base(struct likewise_cell *c)
-{
- if (!c)
- return NULL;
-
- return talloc_asprintf(c, "cn=%s,%s", ADEX_CELL_RDN, c->dn);
-}
-
-/**********************************************************************
- *********************************************************************/
-
- bool cell_search_forest(struct likewise_cell *c)
-{
- uint32_t test_flags = LWCELL_FLAG_SEARCH_FOREST;
-
- return ((c->flags & test_flags) == test_flags);
-}
-
-/**********************************************************************
- *********************************************************************/
-
- uint32_t cell_flags(struct likewise_cell *c)
-{
- if (!c)
- return 0;
-
- return c->flags;
-}
-
-/**********************************************************************
- *********************************************************************/
-
- const char *cell_dns_domain(struct likewise_cell *c)
-{
- if (!c)
- return NULL;
-
- return c->dns_domain;
-}
-
-/**********************************************************************
- *********************************************************************/
-
- ADS_STRUCT *cell_connection(struct likewise_cell *c)
-{
- if (!c)
- return NULL;
-
- return c->conn;
-}
-
-/*
- * Connection functions
- */
-
-/********************************************************************
- *******************************************************************/
-
- NTSTATUS cell_connect(struct likewise_cell *c)
-{
- ADS_STRUCT *ads = NULL;
- ADS_STATUS ads_status;
- fstring dc_name;
- struct sockaddr_storage dcip;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
- /* have to at least have the AD domain name */
-
- if (!c->dns_domain) {
- nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* clear out any old information */
-
- if (c->conn) {
- ads_destroy(&c->conn);
- c->conn = NULL;
- }
-
- /* now setup the new connection */
-
- ads = ads_init(c->dns_domain, NULL, NULL);
- BAIL_ON_PTR_ERROR(ads, nt_status);
-
- ads->auth.password =
- secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
- ads->auth.realm = SMB_STRDUP(lp_realm());
-
- /* Make the connection. We should already have an initial
- TGT using the machine creds */
-
- if (cell_flags(c) & LWCELL_FLAG_GC_CELL) {
- ads_status = ads_connect_gc(ads);
- } else {
- /* Set up server affinity for normal cells and the client
- site name cache */
-
- if (!get_dc_name("", c->dns_domain, dc_name, &dcip)) {
- nt_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- ads_status = ads_connect(ads);
- }
-
-
- c->conn = ads;
-
- nt_status = ads_ntstatus(ads_status);
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- ads_destroy(&ads);
- c->conn = NULL;
- }
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
- NTSTATUS cell_connect_dn(struct likewise_cell **c, const char *dn)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct likewise_cell *new_cell = NULL;
- char *dns_domain = NULL;
-
- if (*c || !dn) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- if ((new_cell = cell_new()) == NULL) {
- nt_status = NT_STATUS_NO_MEMORY;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Set the DNS domain, dn, etc ... and add it to the list */
-
- dns_domain = cell_dn_to_dns(dn);
- cell_set_dns_domain(new_cell, dns_domain);
- SAFE_FREE(dns_domain);
-
- cell_set_dn(new_cell, dn);
-
- nt_status = cell_connect(new_cell);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- *c = new_cell;
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(1,("LWI: Failled to connect to cell \"%s\" (%s)\n",
- dn ? dn : "NULL", nt_errstr(nt_status)));
- talloc_destroy(new_cell);
- }
-
- return nt_status;
-}
-
-
-/********************************************************************
- *******************************************************************/
-
-#define MAX_SEARCH_COUNT 2
-
- ADS_STATUS cell_do_search(struct likewise_cell *c,
- const char *search_base,
- int scope,
- const char *expr,
- const char **attrs,
- LDAPMessage ** msg)
-{
- int search_count = 0;
- ADS_STATUS status;
- NTSTATUS nt_status;
-
- /* check for a NULL connection */
-
- if (!c->conn) {
- nt_status = cell_connect(c);
- if (!NT_STATUS_IS_OK(nt_status)) {
- status = ADS_ERROR_NT(nt_status);
- return status;
- }
- }
-
- DEBUG(10, ("cell_do_search: Base = %s, Filter = %s, Scope = %d, GC = %s\n",
- search_base, expr, scope,
- c->conn->server.gc ? "yes" : "no"));
-
- /* we try multiple times in case the ADS_STRUCT is bad
- and we need to reconnect */
-
- while (search_count < MAX_SEARCH_COUNT) {
- *msg = NULL;
- status = ads_do_search(c->conn, search_base,
- scope, expr, attrs, msg);
- if (ADS_ERR_OK(status)) {
- return status;
- }
-
-
- DEBUG(5, ("cell_do_search: search[%d] failed (%s)\n",
- search_count, ads_errstr(status)));
-
- search_count++;
-
- /* Houston, we have a problem */
-
- if (status.error_type == ENUM_ADS_ERROR_LDAP) {
- switch (status.err.rc) {
- case LDAP_TIMELIMIT_EXCEEDED:
- case LDAP_TIMEOUT:
- case -1: /* we get this error if we cannot contact
- the LDAP server */
- nt_status = cell_connect(c);
- if (!NT_STATUS_IS_OK(nt_status)) {
- status = ADS_ERROR_NT(nt_status);
- return status;
- }
- break;
- default:
- /* we're all done here */
- return status;
- }
- }
- }
-
- DEBUG(5, ("cell_do_search: exceeded maximum search count!\n"));
-
- return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
-}
diff --git a/source/winbindd/idmap_adex/provider_unified.c b/source/winbindd/idmap_adex/provider_unified.c
deleted file mode 100644
index f18534797e..0000000000
--- a/source/winbindd/idmap_adex/provider_unified.c
+++ /dev/null
@@ -1,1180 +0,0 @@
-/*
- * idmap_adex
- *
- * Provider for RFC2307 and SFU AD Forests
- *
- * Copyright (C) Gerald (Jerry) Carter 2006-2008
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include "idmap_adex.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-/* Information needed by the LDAP search filters */
-
-enum filterType { SidFilter, IdFilter, AliasFilter };
-
-struct lwcell_filter
-{
- enum filterType ftype;
- bool use2307;
- union {
- DOM_SID sid;
- struct {
- uint32_t id;
- enum id_type type;
- } id;
- fstring alias;
- } filter;
-};
-
-/********************************************************************
- *******************************************************************/
-
-static char* build_id_filter(uint32_t id,
- enum id_type type,
- uint32_t search_flags)
-{
- char *filter = NULL;
- char *oc_filter, *attr_filter;
- NTSTATUS nt_status;
- TALLOC_CTX *frame = talloc_stackframe();
- bool use2307 = ((search_flags & LWCELL_FLAG_USE_RFC2307_ATTRS)
- == LWCELL_FLAG_USE_RFC2307_ATTRS);
- bool use_gc = ((search_flags & LWCELL_FLAG_SEARCH_FOREST)
- == LWCELL_FLAG_SEARCH_FOREST);
- const char *oc;
-
- /* Construct search filter for objectclass and attributes */
-
- switch (type) {
- case ID_TYPE_UID:
- oc = ADEX_OC_USER;
- if (use2307) {
- oc = ADEX_OC_POSIX_USER;
- if (use_gc) {
- oc = AD_USER;
- }
- }
- oc_filter = talloc_asprintf(frame, "objectclass=%s", oc);
- attr_filter = talloc_asprintf(frame, "%s=%u",
- ADEX_ATTR_UIDNUM, id);
- break;
-
- case ID_TYPE_GID:
- oc = ADEX_OC_GROUP;
- if (use2307) {
- oc = ADEX_OC_POSIX_GROUP;
- if (use_gc) {
- oc = AD_GROUP;
- }
- }
- oc_filter = talloc_asprintf(frame, "objectclass=%s", oc);
- attr_filter = talloc_asprintf(frame, "%s=%u",
- ADEX_ATTR_GIDNUM, id);
- break;
- default:
- return NULL;
- }
-
- BAIL_ON_PTR_ERROR(oc_filter, nt_status);
- BAIL_ON_PTR_ERROR(attr_filter, nt_status);
-
- /* Use "keywords=%s" for non-schema cells */
-
- if (use2307) {
- filter = talloc_asprintf(frame, "(&(%s)(%s))",
- oc_filter, attr_filter);
- } else {
- filter = talloc_asprintf(frame, "(&(keywords=%s)(keywords=%s))",
- oc_filter, attr_filter);
- }
-
- talloc_destroy(oc_filter);
- talloc_destroy(attr_filter);
-
-done:
- /* Don't destroy the stackframe CTX since we are returning
- memory from it */
-
- return filter;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static char* build_alias_filter(const char *alias, uint32_t search_flags)
-{
- char *filter = NULL;
- char *user_attr_filter, *group_attr_filter;
- NTSTATUS nt_status;
- TALLOC_CTX *frame = talloc_stackframe();
- bool use2307 = ((search_flags & LWCELL_FLAG_USE_RFC2307_ATTRS)
- == LWCELL_FLAG_USE_RFC2307_ATTRS);
- bool search_forest = ((search_flags & LWCELL_FLAG_SEARCH_FOREST)
- == LWCELL_FLAG_SEARCH_FOREST);
-
- /* Construct search filter for objectclass and attributes */
-
- user_attr_filter = talloc_asprintf(frame, "%s=%s",
- ADEX_ATTR_UID, alias);
- group_attr_filter = talloc_asprintf(frame, "%s=%s",
- ADEX_ATTR_DISPLAYNAME, alias);
- BAIL_ON_PTR_ERROR(user_attr_filter, nt_status);
- BAIL_ON_PTR_ERROR(group_attr_filter, nt_status);
-
- /* Use "keywords=%s" for non-schema cells */
-
- if (use2307) {
- filter = talloc_asprintf(frame,
- "(|(&(%s)(objectclass=%s))(&(%s)(objectclass=%s)))",
- user_attr_filter,
- search_forest ? AD_USER : ADEX_OC_POSIX_USER,
- group_attr_filter,
- search_forest ? AD_GROUP : ADEX_OC_POSIX_GROUP);
- } else {
- filter = talloc_asprintf(frame,
- "(|(keywords=%s)(keywords=%s))",
- user_attr_filter,
- group_attr_filter);
- }
-
- talloc_destroy(user_attr_filter);
- talloc_destroy(group_attr_filter);
-
-done:
- /* Don't destroy the stackframe CTX since we are returning
- memory from it */
-
- return filter;
-}
-
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS search_cell(struct likewise_cell *c,
- LDAPMessage **msg,
- const struct lwcell_filter *fdata)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX* frame = talloc_stackframe();
- char *filter = NULL;
- const char *base = NULL;
- ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
- const char *attrs[] = { "*", NULL };
- int count;
- char *sid_str;
-
- /* get the filter and other search parameters */
-
- switch (fdata->ftype) {
- case SidFilter:
- sid_str = sid_string_talloc(frame, &fdata->filter.sid);
- BAIL_ON_PTR_ERROR(sid_str, nt_status);
-
- filter = talloc_asprintf(frame, "(keywords=backLink=%s)",
- sid_str);
- break;
- case IdFilter:
- filter = build_id_filter(fdata->filter.id.id,
- fdata->filter.id.type,
- cell_flags(c));
- break;
- case AliasFilter:
- filter = build_alias_filter(fdata->filter.alias,
- cell_flags(c));
- break;
- default:
- nt_status = NT_STATUS_INVALID_PARAMETER;
- break;
- }
- BAIL_ON_PTR_ERROR(filter, nt_status);
-
- base = cell_search_base(c);
- BAIL_ON_PTR_ERROR(base, nt_status);
-
- ads_status = cell_do_search(c, base, LDAP_SCOPE_SUBTREE,
- filter, attrs, msg);
-
- nt_status = ads_ntstatus(ads_status);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Now check that we got only one reply */
-
- count = ads_count_replies(c->conn, *msg);
- if (count < 1) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- if ( count > 1) {
- nt_status = NT_STATUS_DUPLICATE_NAME;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "search_cell", 4);
-
- talloc_destroy(CONST_DISCARD(char*, base));
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS search_domain(struct likewise_cell **cell,
- LDAPMessage **msg,
- const char *dn,
- const DOM_SID *sid)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX* frame = talloc_stackframe();
- int count;
-
- nt_status = dc_search_domains(cell, msg, dn, sid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Now check that we got only one reply */
-
- count = ads_count_replies(cell_connection(*cell), *msg);
- if (count < 1) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- if ( count > 1) {
- nt_status = NT_STATUS_DUPLICATE_NAME;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "search_domain", 4);
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-
-/********************************************************************
- Check that a DN is within the forest scope.
- *******************************************************************/
-
-static bool check_forest_scope(const char *dn)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX *frame = talloc_stackframe();
- char *p = NULL;
- char *q = NULL;
- char *dns_domain = NULL;
- struct winbindd_tdc_domain *domain;
-
- /* If the DN does *not* contain "$LikewiseIdentityCell",
- assume this is a schema mode forest and it is in the
- forest scope by definition. */
-
- if ((p = strstr_m(dn, ADEX_CELL_RDN)) == NULL) {
- nt_status = NT_STATUS_OK;
- goto done;
- }
-
- /* If this is a non-schema forest, then make sure that the DN
- is in the form "...,cn=$LikewiseIdentityCell,DC=..." */
-
- if ((q = strchr_m(p, ',')) == NULL) {
- nt_status = NT_STATUS_OBJECT_NAME_INVALID;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- q++;
- if (StrnCaseCmp(q, "dc=", 3) != 0) {
- nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
-
- dns_domain = cell_dn_to_dns(q);
- BAIL_ON_PTR_ERROR(dns_domain, nt_status);
-
- domain = wcache_tdc_fetch_domain(frame, dns_domain);
- if (!domain) {
- nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- talloc_destroy(frame);
- SAFE_FREE(dns_domain);
-
- return NT_STATUS_IS_OK(nt_status);
-}
-
-
-
-/********************************************************************
- Check that only one result was returned within the forest cell
- scope.
- *******************************************************************/
-
-static NTSTATUS check_result_unique_scoped(ADS_STRUCT **ads_list,
- LDAPMessage **msg_list,
- int num_resp,
- char **dn,
- DOM_SID *user_sid)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- int i;
- ADS_STRUCT *ads = NULL;
- LDAPMessage *msg = NULL;
- int count = 0;
- char *entry_dn = NULL;
- TALLOC_CTX *frame = talloc_stackframe();
-
- if (!dn || !user_sid) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- *dn = NULL;
-
- if (!ads_list || !msg_list || (num_resp == 0)) {
- nt_status = NT_STATUS_NO_SUCH_FILE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Loop over all msgs */
-
- for (i=0; i<num_resp; i++) {
- LDAPMessage *e = ads_first_entry(ads_list[i], msg_list[i]);
-
- while (e) {
- entry_dn = ads_get_dn(ads_list[i], e);
- BAIL_ON_PTR_ERROR(entry_dn, nt_status);
-
- if (check_forest_scope(entry_dn)) {
- count++;
-
- /* If we've already broken the condition, no
- need to continue */
-
- if (count > 1) {
- nt_status = NT_STATUS_DUPLICATE_NAME;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- ads = ads_list[i];
- msg = e;
- *dn = SMB_STRDUP(entry_dn);
- BAIL_ON_PTR_ERROR((*dn), nt_status);
- }
-
- e = ads_next_entry(ads_list[i], e);
- SAFE_FREE(entry_dn);
- }
- }
-
- if (!ads || !msg) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* If we made is through the loop, then grab the user_sid and
- run home to base */
-
- /*
- Try and get the SID from either objectSid or keywords.
- We cannot use pull_sid() here since we want to try
- both methods and not only one or the other (and we
- have no full likewise_cell struct.
-
- Fail if both are unavailable
- */
-
- if (!ads_pull_sid(ads, msg, "objectSid", user_sid)) {
- char **keywords;
- char *s;
- size_t num_lines = 0;
-
- keywords = ads_pull_strings(ads, frame, msg, "keywords",
- &num_lines);
- BAIL_ON_PTR_ERROR(keywords, nt_status);
-
- s = find_attr_string(keywords, num_lines, "backLink");
- if (!s) {
- nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- if (!string_to_sid(user_sid, s)) {
- nt_status = NT_STATUS_INVALID_SID;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- SAFE_FREE(*dn);
- }
-
- talloc_destroy(frame);
- SAFE_FREE(entry_dn);
-
- return nt_status;
-}
-
-/********************************************************************
- Search all forests. Each forest can have it's own forest-cell
- settings so we have to generate the filter for each search.
- We don't use gc_search_all_forests() since we may have a different
- schema model in each forest and need to construct the search
- filter for each GC search.
- *******************************************************************/
-
-static NTSTATUS search_forest(struct likewise_cell *forest_cell,
- LDAPMessage **msg,
- const struct lwcell_filter *fdata)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX *frame = talloc_stackframe();
- char *filter = NULL;
- char *dn = NULL;
- struct gc_info *gc = NULL;
- ADS_STRUCT **ads_list = NULL;
- LDAPMessage **msg_list = NULL;
- int num_resp = 0;
- LDAPMessage *m;
- DOM_SID user_sid;
- struct likewise_cell *domain_cell = NULL;
-
- if ((gc = gc_search_start()) == NULL) {
- nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- while (gc) {
- char *sid_binstr = NULL;
- uint32_t flags = LWCELL_FLAG_SEARCH_FOREST;
-
- m = NULL;
-
- flags |= cell_flags(gc->forest_cell);
-
- switch (fdata->ftype) {
- case SidFilter:
- sid_binstr = sid_binstring(&fdata->filter.sid);
- BAIL_ON_PTR_ERROR(sid_binstr, nt_status);
-
- filter = talloc_asprintf(frame, "(objectSid=%s)", sid_binstr);
- SAFE_FREE(sid_binstr);
- break;
- case IdFilter:
- filter = build_id_filter(fdata->filter.id.id,
- fdata->filter.id.type, flags);
- break;
- case AliasFilter:
- filter = build_alias_filter(fdata->filter.alias, flags);
- break;
- }
-
- /* First find the sparse object in GC */
- nt_status = gc_search_forest(gc, &m, filter);
- if (!NT_STATUS_IS_OK(nt_status)) {
- gc = gc->next;
- continue;
- }
-
- nt_status = add_ads_result_to_array(cell_connection(gc->forest_cell),
- m, &ads_list, &msg_list,
- &num_resp);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- gc = gc->next;
- }
-
- /* Uniqueness check across forests */
-
- nt_status = check_result_unique_scoped(ads_list, msg_list, num_resp,
- &dn, &user_sid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = search_domain(&domain_cell, &m, dn, &user_sid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Save the connection and results in the return parameters */
-
- forest_cell->gc_search_cell = domain_cell;
- *msg = m;
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "search_forest", 4);
-
- SAFE_FREE(dn);
-
- free_result_array(ads_list, msg_list, num_resp);
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS search_cell_list(struct likewise_cell **c,
- LDAPMessage **m,
- const struct lwcell_filter *fdata)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct likewise_cell *cell = NULL;
- LDAPMessage *msg = NULL;
- struct likewise_cell *result_cell = NULL;
-
- if ((cell = cell_list_head()) == NULL) {
- nt_status = NT_STATUS_INVALID_SERVER_STATE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- while (cell) {
- /* Clear any previous GC search results */
-
- cell->gc_search_cell = NULL;
-
- if (cell_search_forest(cell)) {
- nt_status = search_forest(cell, &msg, fdata);
- } else {
- nt_status = search_cell(cell, &msg, fdata);
- }
-
- /* Always point to the search result cell.
- In forests this might be for another domain
- which means the schema model may be different */
-
- result_cell = cell->gc_search_cell ?
- cell->gc_search_cell : cell;
-
- /* Check if we are done */
-
- if (NT_STATUS_IS_OK(nt_status)) {
- break;
- }
-
- /* No luck. Free memory and hit the next cell.
- Forest searches always set the gc_search_cell
- so give preference to that connection if possible. */
-
- ads_msgfree(cell_connection(result_cell), msg);
- msg = NULL;
-
- cell = cell->next;
- }
-
- /* This might be assigning NULL but that is ok as long as we
- give back the proper error code */
-
- *c = result_cell;
- *m = msg;
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "search_cell_list", 3);
-
- return nt_status;
-}
-
-/********************************************************************
- Pull the SID from an object which is always stored in the keywords
- attribute as "backLink=S-1-5-21-..."
- *******************************************************************/
-
-static NTSTATUS pull_sid(struct likewise_cell *c,
- LDAPMessage *msg,
- DOM_SID *sid)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX *frame = talloc_stackframe();
- ADS_STRUCT *ads = NULL;
-
- ads = cell_connection(c);
-
- /*
- We have two ways of getting the sid:
- (a) from the objectSID in case of a GC search,
- (b) from backLink in the case of a cell search.
- Pull the keywords attributes and grab the backLink.
- */
-
- if (!ads_pull_sid(ads, msg, "objectSid", sid)) {
- char **keywords;
- char *s;
- size_t num_lines = 0;
-
- keywords = ads_pull_strings(ads, frame, msg,
- "keywords", &num_lines);
- BAIL_ON_PTR_ERROR(keywords, nt_status);
-
- s = find_attr_string(keywords, num_lines, "backLink");
- if (!s) {
- nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- if (!string_to_sid(sid, s)) {
- nt_status = NT_STATUS_INVALID_SID;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS get_object_type(struct likewise_cell *c,
- LDAPMessage *msg,
- enum id_type *type)
-{
- TALLOC_CTX *ctx = talloc_stackframe();
- char **oc_list = NULL;
- NTSTATUS nt_status = NT_STATUS_OK;
- size_t list_size = 0;
- char *s = NULL;
- ADS_STRUCT *ads = NULL;
-
- ads = cell_connection(c);
-
- /* Deal with RFC 2307 support first */
-
- if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
- oc_list = ads_pull_strings(ads, ctx, msg,
- "objectClass", &list_size);
- if (!oc_list) {
- nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- goto done;
- }
-
- /* Check for posix classes and AD classes */
-
- if (is_object_class(oc_list, list_size, ADEX_OC_POSIX_USER)
- || is_object_class(oc_list, list_size, AD_USER)) {
- *type = ID_TYPE_UID;
- } else if (is_object_class(oc_list, list_size, ADEX_OC_POSIX_GROUP)
- || is_object_class(oc_list, list_size, AD_GROUP)) {
- *type = ID_TYPE_GID;
- } else {
- *type = ID_TYPE_NOT_SPECIFIED;
- nt_status = NT_STATUS_INVALID_PARAMETER;
- }
- } else {
- /* Default to non-schema mode */
-
- oc_list = ads_pull_strings(ads, ctx, msg,
- "keywords", &list_size);
- if (!oc_list) {
- nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- goto done;
- }
-
- s = find_attr_string(oc_list, list_size, "objectClass");
- if (!s) {
- nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- goto done;
- }
-
- if (strequal(s, ADEX_OC_USER)) {
- *type = ID_TYPE_UID;
- } else if (strequal(s, ADEX_OC_GROUP)) {
- *type = ID_TYPE_GID;
- } else {
- *type = ID_TYPE_NOT_SPECIFIED;
- nt_status = NT_STATUS_INVALID_PARAMETER;
- }
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- talloc_destroy(ctx);
-
- return nt_status;
-}
-
-/********************************************************************
- Pull an attribute uint32_t value
- *******************************************************************/
-
-static NTSTATUS get_object_uint32(struct likewise_cell *c,
- LDAPMessage *msg,
- const char *attrib,
- uint32_t *x)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- char **keywords = NULL;
- size_t list_size = 0;
- TALLOC_CTX *frame = talloc_stackframe();
- ADS_STRUCT *ads = NULL;
-
- ads = cell_connection(c);
-
- /* Deal with RFC2307 schema */
-
- if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
- if (!ads_pull_uint32(ads, msg, attrib, x)) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
- } else {
- /* Non-schema mode */
- char *s = NULL;
- uint32_t num;
-
- keywords = ads_pull_strings(ads, frame, msg, "keywords",
- &list_size);
- BAIL_ON_PTR_ERROR(keywords, nt_status);
-
- s = find_attr_string(keywords, list_size, attrib);
- if (!s) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- num = strtoll(s, NULL, 10);
- if (errno == ERANGE) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
- *x = num;
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS get_object_id(struct likewise_cell *c,
- LDAPMessage *msg,
- enum id_type type,
- uint32_t *id)
-{
- NTSTATUS nt_status = NT_STATUS_OK;
- const char *id_attr;
-
- /* Figure out which attribute we need to pull */
-
- switch (type) {
- case ID_TYPE_UID:
- id_attr = ADEX_ATTR_UIDNUM;
- break;
- case ID_TYPE_GID:
- id_attr = ADEX_ATTR_GIDNUM;
- break;
- default:
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- break;
- }
-
- nt_status = get_object_uint32(c, msg, id_attr, id);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- return nt_status;
-}
-
-/********************************************************************
- Pull the uid/gid and type from an object. This differs depending on
- the cell flags.
- *******************************************************************/
-
-static NTSTATUS pull_id(struct likewise_cell *c,
- LDAPMessage *msg,
- uint32_t *id,
- enum id_type *type)
-{
- NTSTATUS nt_status;
-
- nt_status = get_object_type(c, msg, type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = get_object_id(c, msg, *type, id);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- return nt_status;
-}
-
-/********************************************************************
- Pull an attribute string value
- *******************************************************************/
-
-static NTSTATUS get_object_string(struct likewise_cell *c,
- LDAPMessage *msg,
- TALLOC_CTX *ctx,
- const char *attrib,
- char **string)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- char **keywords = NULL;
- size_t list_size = 0;
- TALLOC_CTX *frame = talloc_stackframe();
- ADS_STRUCT *ads = NULL;
-
- *string = NULL;
-
- ads = cell_connection(c);
-
- /* Deal with RFC2307 schema */
-
- if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
- *string = ads_pull_string(ads, ctx, msg, attrib);
- } else {
- /* Non-schema mode */
-
- char *s = NULL;
-
- keywords = ads_pull_strings(ads, frame, msg,
- "keywords", &list_size);
- if (!keywords) {
- nt_status = NT_STATUS_NO_MEMORY;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
- s = find_attr_string(keywords, list_size, attrib);
- if (s) {
- *string = talloc_strdup(ctx, s);
- }
- }
-
- if (!*string) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- Pull the struct passwd fields for a user
- *******************************************************************/
-
-static NTSTATUS pull_nss_info(struct likewise_cell *c,
- LDAPMessage *msg,
- TALLOC_CTX *ctx,
- char **homedir,
- char **shell,
- char **gecos,
- gid_t *p_gid)
-{
- NTSTATUS nt_status;
-
- nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_HOMEDIR, homedir);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_SHELL, shell);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_GECOS, gecos);
- /* Gecos is often not set so ignore failures */
-
- nt_status = get_object_uint32(c, msg, ADEX_ATTR_GIDNUM, p_gid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- return nt_status;
-}
-
-/********************************************************************
- Pull the struct passwd fields for a user
- *******************************************************************/
-
-static NTSTATUS pull_alias(struct likewise_cell *c,
- LDAPMessage *msg,
- TALLOC_CTX *ctx,
- char **alias)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- enum id_type type;
- const char *attr = NULL;
-
- /* Figure out if this is a user or a group */
-
- nt_status = get_object_type(c, msg, &type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- switch (type) {
- case ID_TYPE_UID:
- attr = ADEX_ATTR_UID;
- break;
- case ID_TYPE_GID:
- /* What is the group attr for RFC2307 Forests? */
- attr = ADEX_ATTR_DISPLAYNAME;
- break;
- default:
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- break;
- }
-
- nt_status = get_object_string(c, msg, ctx, attr, alias);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS _ccp_get_sid_from_id(DOM_SID * sid,
- uint32_t id, enum id_type type)
-{
- struct likewise_cell *cell = NULL;
- LDAPMessage *msg = NULL;
- NTSTATUS nt_status;
- struct lwcell_filter filter;
-
- filter.ftype = IdFilter;
- filter.filter.id.id = id;
- filter.filter.id.type = type;
-
- nt_status = search_cell_list(&cell, &msg, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = pull_sid(cell, msg, sid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- ads_msgfree(cell->conn, msg);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS _ccp_get_id_from_sid(uint32_t * id,
- enum id_type *type,
- const DOM_SID * sid)
-{
- struct likewise_cell *cell = NULL;
- LDAPMessage *msg = NULL;
- NTSTATUS nt_status;
- struct lwcell_filter filter;
-
- filter.ftype = SidFilter;
- sid_copy(&filter.filter.sid, sid);
-
- nt_status = search_cell_list(&cell, &msg, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = pull_id(cell, msg, id, type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if (*id < min_id_value()) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
-done:
- ads_msgfree(cell->conn, msg);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS _ccp_nss_get_info(const DOM_SID * sid,
- TALLOC_CTX * ctx,
- char **homedir,
- char **shell,
- char **gecos, gid_t * p_gid)
-{
- struct likewise_cell *cell = NULL;
- LDAPMessage *msg = NULL;
- NTSTATUS nt_status;
- struct lwcell_filter filter;
- enum id_type type;
-
- filter.ftype = SidFilter;
- sid_copy(&filter.filter.sid, sid);
-
- nt_status = search_cell_list(&cell, &msg, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = get_object_type(cell, msg, &type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if (type != ID_TYPE_UID) {
- nt_status = NT_STATUS_NO_SUCH_USER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- nt_status = pull_nss_info(cell, msg, ctx, homedir, shell, gecos,
- (uint32_t*) p_gid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- ads_msgfree(cell->conn, msg);
-
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _ccp_map_to_alias(TALLOC_CTX *ctx,
- const char *domain,
- const char *name, char **alias)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- DOM_SID sid;
- struct likewise_cell *cell = NULL;
- LDAPMessage *msg = NULL;
- struct lwcell_filter filter;
- enum lsa_SidType sid_type;
-
- /* Convert the name to a SID */
-
- nt_status = gc_name_to_sid(domain, name, &sid, &sid_type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Find the user/group */
-
- filter.ftype = SidFilter;
- sid_copy(&filter.filter.sid, &sid);
-
- nt_status = search_cell_list(&cell, &msg, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Pull the alias and return */
-
- nt_status = pull_alias(cell, msg, ctx, alias);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "map_to_alias", 3);
-
- talloc_destroy(frame);
- ads_msgfree(cell_connection(cell), msg);
-
- return nt_status;
-}
-
-/**********************************************************************
- Map from an alias name to the canonical, qualified name.
- Ensure that the alias is only pull from the closest in which
- the user or gorup is enabled in
- *********************************************************************/
-
-static NTSTATUS _ccp_map_from_alias(TALLOC_CTX *mem_ctx,
- const char *domain,
- const char *alias, char **name)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- DOM_SID sid;
- struct likewise_cell *cell_alias = NULL;
- LDAPMessage *msg_alias = NULL;
- struct likewise_cell *cell_sid = NULL;
- LDAPMessage *msg_sid = NULL;
- struct lwcell_filter filter;
- char *canonical_name = NULL;
- enum lsa_SidType type;
-
- /* Find the user/group */
-
- filter.ftype = AliasFilter;
- fstrcpy(filter.filter.alias, alias);
-
- nt_status = search_cell_list(&cell_alias, &msg_alias, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = pull_sid(cell_alias, msg_alias, &sid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Now search again for the SID according to the cell list.
- Verify that the cell of both search results is the same
- so that we only match an alias from the closest cell
- in which a user/group has been instantied. */
-
- filter.ftype = SidFilter;
- sid_copy(&filter.filter.sid, &sid);
-
- nt_status = search_cell_list(&cell_sid, &msg_sid, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if (cell_alias != cell_sid) {
- nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Finally do the GC sid/name conversion */
-
- nt_status = gc_sid_to_name(&sid, &canonical_name, &type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- *name = talloc_strdup(mem_ctx, canonical_name);
- BAIL_ON_PTR_ERROR((*name), nt_status);
-
- nt_status = NT_STATUS_OK;
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "map_from_alias", 3);
-
- ads_msgfree(cell_connection(cell_alias), msg_alias);
- ads_msgfree(cell_connection(cell_sid), msg_sid);
-
- SAFE_FREE(canonical_name);
-
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-struct cell_provider_api ccp_unified = {
- .get_sid_from_id = _ccp_get_sid_from_id,
- .get_id_from_sid = _ccp_get_id_from_sid,
- .get_nss_info = _ccp_nss_get_info,
- .map_to_alias = _ccp_map_to_alias,
- .map_from_alias = _ccp_map_from_alias
-};
diff --git a/source/winbindd/idmap_cache.c b/source/winbindd/idmap_cache.c
new file mode 100644
index 0000000000..cf46196ebe
--- /dev/null
+++ b/source/winbindd/idmap_cache.c
@@ -0,0 +1,534 @@
+/*
+ Unix SMB/CIFS implementation.
+ ID Mapping Cache
+
+ based on gencache
+
+ Copyright (C) Simo Sorce 2006
+ Copyright (C) Rafal Szczesniak 2002
+
+ 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
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.*/
+
+#include "includes.h"
+#include "winbindd.h"
+
+#define TIMEOUT_LEN 12
+#define IDMAP_CACHE_DATA_FMT "%12u/%s"
+#define IDMAP_READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us"
+
+struct idmap_cache_ctx {
+ TDB_CONTEXT *tdb;
+};
+
+static int idmap_cache_destructor(struct idmap_cache_ctx *cache)
+{
+ int ret = 0;
+
+ if (cache && cache->tdb) {
+ ret = tdb_close(cache->tdb);
+ cache->tdb = NULL;
+ }
+
+ return ret;
+}
+
+struct idmap_cache_ctx *idmap_cache_init(TALLOC_CTX *memctx)
+{
+ struct idmap_cache_ctx *cache;
+ char* cache_fname = NULL;
+
+ cache = talloc(memctx, struct idmap_cache_ctx);
+ if ( ! cache) {
+ DEBUG(0, ("Out of memory!\n"));
+ return NULL;
+ }
+
+ cache_fname = lock_path("idmap_cache.tdb");
+
+ DEBUG(10, ("Opening cache file at %s\n", cache_fname));
+
+ cache->tdb = tdb_open_log(cache_fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+
+ if (!cache->tdb) {
+ DEBUG(5, ("Attempt to open %s has failed.\n", cache_fname));
+ return NULL;
+ }
+
+ talloc_set_destructor(cache, idmap_cache_destructor);
+
+ return cache;
+}
+
+void idmap_cache_shutdown(struct idmap_cache_ctx *cache)
+{
+ talloc_free(cache);
+}
+
+NTSTATUS idmap_cache_build_sidkey(TALLOC_CTX *ctx, char **sidkey, const struct id_map *id)
+{
+ fstring sidstr;
+
+ *sidkey = talloc_asprintf(ctx, "IDMAP/SID/%s",
+ sid_to_fstring(sidstr, id->sid));
+ if ( ! *sidkey) {
+ DEBUG(1, ("failed to build sidkey, OOM?\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS idmap_cache_build_idkey(TALLOC_CTX *ctx, char **idkey, const struct id_map *id)
+{
+ *idkey = talloc_asprintf(ctx, "IDMAP/%s/%lu",
+ (id->xid.type==ID_TYPE_UID)?"UID":"GID",
+ (unsigned long)id->xid.id);
+ if ( ! *idkey) {
+ DEBUG(1, ("failed to build idkey, OOM?\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS idmap_cache_set(struct idmap_cache_ctx *cache, const struct id_map *id)
+{
+ NTSTATUS ret;
+ time_t timeout = time(NULL) + lp_idmap_cache_time();
+ TDB_DATA databuf;
+ char *sidkey;
+ char *idkey;
+ char *valstr;
+
+ /* Don't cache lookups in the S-1-22-{1,2} domain */
+ if ( (id->xid.type == ID_TYPE_UID) &&
+ sid_check_is_in_unix_users(id->sid) )
+ {
+ return NT_STATUS_OK;
+ }
+ if ( (id->xid.type == ID_TYPE_GID) &&
+ sid_check_is_in_unix_groups(id->sid) )
+ {
+ return NT_STATUS_OK;
+ }
+
+
+ ret = idmap_cache_build_sidkey(cache, &sidkey, id);
+ if (!NT_STATUS_IS_OK(ret)) return ret;
+
+ /* use sidkey as the local memory ctx */
+ ret = idmap_cache_build_idkey(sidkey, &idkey, id);
+ if (!NT_STATUS_IS_OK(ret)) {
+ goto done;
+ }
+
+ /* save SID -> ID */
+
+ /* use sidkey as the local memory ctx */
+ valstr = talloc_asprintf(sidkey, IDMAP_CACHE_DATA_FMT, (int)timeout, idkey);
+ if (!valstr) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ databuf = string_term_tdb_data(valstr);
+ DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
+ " %s (%d seconds %s)\n", sidkey, valstr , ctime(&timeout),
+ (int)(timeout - time(NULL)),
+ timeout > time(NULL) ? "ahead" : "in the past"));
+
+ if (tdb_store_bystring(cache->tdb, sidkey, databuf, TDB_REPLACE) != 0) {
+ DEBUG(3, ("Failed to store cache entry!\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* save ID -> SID */
+
+ /* use sidkey as the local memory ctx */
+ valstr = talloc_asprintf(sidkey, IDMAP_CACHE_DATA_FMT, (int)timeout, sidkey);
+ if (!valstr) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ databuf = string_term_tdb_data(valstr);
+ DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
+ " %s (%d seconds %s)\n", idkey, valstr, ctime(&timeout),
+ (int)(timeout - time(NULL)),
+ timeout > time(NULL) ? "ahead" : "in the past"));
+
+ if (tdb_store_bystring(cache->tdb, idkey, databuf, TDB_REPLACE) != 0) {
+ DEBUG(3, ("Failed to store cache entry!\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ ret = NT_STATUS_OK;
+
+done:
+ talloc_free(sidkey);
+ return ret;
+}
+
+NTSTATUS idmap_cache_set_negative_sid(struct idmap_cache_ctx *cache, const struct id_map *id)
+{
+ NTSTATUS ret;
+ time_t timeout = time(NULL) + lp_idmap_negative_cache_time();
+ TDB_DATA databuf;
+ char *sidkey;
+ char *valstr;
+
+ ret = idmap_cache_build_sidkey(cache, &sidkey, id);
+ if (!NT_STATUS_IS_OK(ret)) return ret;
+
+ /* use sidkey as the local memory ctx */
+ valstr = talloc_asprintf(sidkey, IDMAP_CACHE_DATA_FMT, (int)timeout, "IDMAP/NEGATIVE");
+ if (!valstr) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ databuf = string_term_tdb_data(valstr);
+ DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
+ " %s (%d seconds %s)\n", sidkey, valstr, ctime(&timeout),
+ (int)(timeout - time(NULL)),
+ timeout > time(NULL) ? "ahead" : "in the past"));
+
+ if (tdb_store_bystring(cache->tdb, sidkey, databuf, TDB_REPLACE) != 0) {
+ DEBUG(3, ("Failed to store cache entry!\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+done:
+ talloc_free(sidkey);
+ return ret;
+}
+
+NTSTATUS idmap_cache_set_negative_id(struct idmap_cache_ctx *cache, const struct id_map *id)
+{
+ NTSTATUS ret;
+ time_t timeout = time(NULL) + lp_idmap_negative_cache_time();
+ TDB_DATA databuf;
+ char *idkey;
+ char *valstr;
+
+ ret = idmap_cache_build_idkey(cache, &idkey, id);
+ if (!NT_STATUS_IS_OK(ret)) return ret;
+
+ /* use idkey as the local memory ctx */
+ valstr = talloc_asprintf(idkey, IDMAP_CACHE_DATA_FMT, (int)timeout, "IDMAP/NEGATIVE");
+ if (!valstr) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ databuf = string_term_tdb_data(valstr);
+ DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
+ " %s (%d seconds %s)\n", idkey, valstr, ctime(&timeout),
+ (int)(timeout - time(NULL)),
+ timeout > time(NULL) ? "ahead" : "in the past"));
+
+ if (tdb_store_bystring(cache->tdb, idkey, databuf, TDB_REPLACE) != 0) {
+ DEBUG(3, ("Failed to store cache entry!\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+done:
+ talloc_free(idkey);
+ return ret;
+}
+
+NTSTATUS idmap_cache_fill_map(struct id_map *id, const char *value)
+{
+ char *rem;
+
+ /* see if it is a sid */
+ if ( ! strncmp("IDMAP/SID/", value, 10)) {
+
+ if ( ! string_to_sid(id->sid, &value[10])) {
+ goto failed;
+ }
+
+ id->status = ID_MAPPED;
+
+ return NT_STATUS_OK;
+ }
+
+ /* not a SID see if it is an UID or a GID */
+ if ( ! strncmp("IDMAP/UID/", value, 10)) {
+
+ /* a uid */
+ id->xid.type = ID_TYPE_UID;
+
+ } else if ( ! strncmp("IDMAP/GID/", value, 10)) {
+
+ /* a gid */
+ id->xid.type = ID_TYPE_GID;
+
+ } else {
+
+ /* a completely bogus value bail out */
+ goto failed;
+ }
+
+ id->xid.id = strtol(&value[10], &rem, 0);
+ if (*rem != '\0') {
+ goto failed;
+ }
+
+ id->status = ID_MAPPED;
+
+ return NT_STATUS_OK;
+
+failed:
+ DEBUG(1, ("invalid value: %s\n", value));
+ id->status = ID_UNKNOWN;
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+}
+
+bool idmap_cache_is_negative(const char *val)
+{
+ if ( ! strcmp("IDMAP/NEGATIVE", val)) {
+ return True;
+ }
+ return False;
+}
+
+/* search the cahce for the SID an return a mapping if found *
+ *
+ * 4 cases are possible
+ *
+ * 1 map found
+ * in this case id->status = ID_MAPPED and NT_STATUS_OK is returned
+ * 2 map not found
+ * in this case id->status = ID_UNKNOWN and NT_STATUS_NONE_MAPPED is returned
+ * 3 negative cache found
+ * in this case id->status = ID_UNMAPPED and NT_STATUS_OK is returned
+ * 4 map found but timer expired
+ * in this case id->status = ID_EXPIRED and NT_STATUS_SYNCHRONIZATION_REQUIRED
+ * is returned. In this case revalidation of the cache is needed.
+ */
+
+NTSTATUS idmap_cache_map_sid(struct idmap_cache_ctx *cache, struct id_map *id)
+{
+ NTSTATUS ret;
+ TDB_DATA databuf;
+ time_t t;
+ char *sidkey;
+ char *endptr;
+ struct winbindd_domain *our_domain = find_our_domain();
+ time_t now = time(NULL);
+
+ /* make sure it is marked as not mapped by default */
+ id->status = ID_UNKNOWN;
+
+ ret = idmap_cache_build_sidkey(cache, &sidkey, id);
+ if (!NT_STATUS_IS_OK(ret)) return ret;
+
+ databuf = tdb_fetch_bystring(cache->tdb, sidkey);
+
+ if (databuf.dptr == NULL) {
+ DEBUG(10, ("Cache entry with key = %s couldn't be found\n", sidkey));
+ ret = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ t = strtol((const char *)databuf.dptr, &endptr, 10);
+
+ if ((endptr == NULL) || (*endptr != '/')) {
+ DEBUG(2, ("Invalid gencache data format: %s\n", (const char *)databuf.dptr));
+ /* remove the entry */
+ tdb_delete_bystring(cache->tdb, sidkey);
+ ret = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ /* check it is not negative */
+ if (strcmp("IDMAP/NEGATIVE", endptr+1) != 0) {
+
+ DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
+ "timeout = %s", t > now ? "valid" :
+ "expired", sidkey, endptr+1, ctime(&t)));
+
+ /* this call if successful will also mark the entry as mapped */
+ ret = idmap_cache_fill_map(id, endptr+1);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ /* if not valid form delete the entry */
+ tdb_delete_bystring(cache->tdb, sidkey);
+ ret = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ /* here ret == NT_STATUS_OK and id->status = ID_MAPPED */
+
+ if (t <= now) {
+ /* If we've been told to be offline - stay in
+ that state... */
+ if ( IS_DOMAIN_OFFLINE(our_domain) ) {
+ DEBUG(10,("idmap_cache_map_sid: idmap is offline\n"));
+ goto done;
+ }
+
+ /* We're expired, set an error code
+ for upper layer */
+ ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
+ }
+
+ goto done;
+ }
+
+ /* Was a negative cache hit */
+
+ /* Ignore the negative cache when offline */
+
+ if ( IS_DOMAIN_OFFLINE(our_domain) ) {
+ DEBUG(10,("idmap_cache_map_sid: idmap is offline\n"));
+ goto done;
+ }
+
+
+ /* Check for valid or expired cache hits */
+ if (t <= now) {
+ /* We're expired. Return not mapped */
+ ret = NT_STATUS_NONE_MAPPED;
+ } else {
+ /* this is not mapped as it was a negative cache hit */
+ id->status = ID_UNMAPPED;
+ ret = NT_STATUS_OK;
+ }
+
+done:
+ SAFE_FREE(databuf.dptr);
+ talloc_free(sidkey);
+ return ret;
+}
+
+/* search the cahce for the ID an return a mapping if found *
+ *
+ * 4 cases are possible
+ *
+ * 1 map found
+ * in this case id->status = ID_MAPPED and NT_STATUS_OK is returned
+ * 2 map not found
+ * in this case id->status = ID_UNKNOWN and NT_STATUS_NONE_MAPPED is returned
+ * 3 negative cache found
+ * in this case id->status = ID_UNMAPPED and NT_STATUS_OK is returned
+ * 4 map found but timer expired
+ * in this case id->status = ID_EXPIRED and NT_STATUS_SYNCHRONIZATION_REQUIRED
+ * is returned. In this case revalidation of the cache is needed.
+ */
+
+NTSTATUS idmap_cache_map_id(struct idmap_cache_ctx *cache, struct id_map *id)
+{
+ NTSTATUS ret;
+ TDB_DATA databuf;
+ time_t t;
+ char *idkey;
+ char *endptr;
+ struct winbindd_domain *our_domain = find_our_domain();
+ time_t now = time(NULL);
+
+ /* make sure it is marked as unknown by default */
+ id->status = ID_UNKNOWN;
+
+ ret = idmap_cache_build_idkey(cache, &idkey, id);
+ if (!NT_STATUS_IS_OK(ret)) return ret;
+
+ databuf = tdb_fetch_bystring(cache->tdb, idkey);
+
+ if (databuf.dptr == NULL) {
+ DEBUG(10, ("Cache entry with key = %s couldn't be found\n", idkey));
+ ret = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ t = strtol((const char *)databuf.dptr, &endptr, 10);
+
+ if ((endptr == NULL) || (*endptr != '/')) {
+ DEBUG(2, ("Invalid gencache data format: %s\n", (const char *)databuf.dptr));
+ /* remove the entry */
+ tdb_delete_bystring(cache->tdb, idkey);
+ ret = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ /* check it is not negative */
+ if (strcmp("IDMAP/NEGATIVE", endptr+1) != 0) {
+
+ DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
+ "timeout = %s", t > now ? "valid" :
+ "expired", idkey, endptr+1, ctime(&t)));
+
+ /* this call if successful will also mark the entry as mapped */
+ ret = idmap_cache_fill_map(id, endptr+1);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ /* if not valid form delete the entry */
+ tdb_delete_bystring(cache->tdb, idkey);
+ ret = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ /* here ret == NT_STATUS_OK and id->mapped = ID_MAPPED */
+
+ if (t <= now) {
+ /* If we've been told to be offline - stay in
+ that state... */
+ if ( IS_DOMAIN_OFFLINE(our_domain) ) {
+ DEBUG(10,("idmap_cache_map_sid: idmap is offline\n"));
+ goto done;
+ }
+
+ /* We're expired, set an error code
+ for upper layer */
+ ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
+ }
+
+ goto done;
+ }
+
+ /* Was a negative cache hit */
+
+ /* Ignore the negative cache when offline */
+
+ if ( IS_DOMAIN_OFFLINE(our_domain) ) {
+ DEBUG(10,("idmap_cache_map_sid: idmap is offline\n"));
+ ret = NT_STATUS_NONE_MAPPED;
+
+ goto done;
+ }
+
+ /* Process the negative cache hit */
+
+ if (t <= now) {
+ /* We're expired. Return not mapped */
+ ret = NT_STATUS_NONE_MAPPED;
+ } else {
+ /* this is not mapped is it was a negative cache hit */
+ id->status = ID_UNMAPPED;
+ ret = NT_STATUS_OK;
+ }
+
+done:
+ SAFE_FREE(databuf.dptr);
+ talloc_free(idkey);
+ return ret;
+}
+
diff --git a/source/winbindd/idmap_hash/idmap_hash.c b/source/winbindd/idmap_hash/idmap_hash.c
deleted file mode 100644
index a050f99bc8..0000000000
--- a/source/winbindd/idmap_hash/idmap_hash.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * idmap_hash.c
- *
- * Copyright (C) Gerald Carter <jerry@samba.org> 2007 - 2008
- *
- * 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
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "includes.h"
-#include "winbindd/winbindd.h"
-#include "idmap_hash.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-struct sid_hash_table {
- DOM_SID *sid;
-};
-
-struct sid_hash_table *hashed_domains = NULL;
-
-/*********************************************************************
- Hash a domain SID (S-1-5-12-aaa-bbb-ccc) to a 12bit number
- ********************************************************************/
-
-static uint32_t hash_domain_sid(const DOM_SID *sid)
-{
- uint32_t hash;
-
- if (sid->num_auths != 4)
- return 0;
-
- /* XOR the last three subauths */
-
- hash = ((sid->sub_auths[1] ^ sid->sub_auths[2]) ^ sid->sub_auths[3]);
-
- /* Take all 32-bits into account when generating the 12-bit
- hash value */
- hash = (((hash & 0xFFF00000) >> 20)
- + ((hash & 0x000FFF00) >> 8)
- + (hash & 0x000000FF)) & 0x0000FFF;
-
- /* return a 12-bit hash value */
-
- return hash;
-}
-
-/*********************************************************************
- Hash a Relative ID to a 20 bit number
- ********************************************************************/
-
-static uint32_t hash_rid(uint32_t rid)
-{
- /* 20 bits for the rid which allows us to support
- the first 100K users/groups in a domain */
-
- return (rid & 0x0007FFFF);
-}
-
-/*********************************************************************
- ********************************************************************/
-
-static uint32_t combine_hashes(uint32_t h_domain,
- uint32_t h_rid)
-{
- uint32_t return_id = 0;
-
- /* shift the hash_domain 19 bits to the left and OR with the
- hash_rid */
-
- return_id = ((h_domain<<19) | h_rid);
-
- return return_id;
-}
-
-/*********************************************************************
- ********************************************************************/
-
-static void separate_hashes(uint32_t id,
- uint32_t *h_domain,
- uint32_t *h_rid)
-{
- *h_rid = id & 0x0007FFFF;
- *h_domain = (id & 0x7FF80000) >> 19;
-
- return;
-}
-
-
-/*********************************************************************
- ********************************************************************/
-
-static NTSTATUS be_init(struct idmap_domain *dom,
- const char *params)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct winbindd_tdc_domain *dom_list = NULL;
- size_t num_domains = 0;
- int i;
-
- /* If the domain SID hash talbe has been initialized, assume
- that we completed this function previously */
-
- if ( hashed_domains ) {
- nt_status = NT_STATUS_OK;
- goto done;
- }
-
- if (!wcache_tdc_fetch_list(&dom_list, &num_domains)) {
- nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Create the hash table of domain SIDs */
-
- hashed_domains = TALLOC_ZERO_ARRAY(NULL, struct sid_hash_table, 4096);
- BAIL_ON_PTR_NT_ERROR(hashed_domains, nt_status);
-
- /* create the hash table of domain SIDs */
-
- for (i=0; i<num_domains; i++) {
- uint32_t hash;
-
- if (is_null_sid(&dom_list[i].sid))
- continue;
- if ((hash = hash_domain_sid(&dom_list[i].sid)) == 0)
- continue;
-
- DEBUG(5,("hash:be_init() Adding %s (%s) -> %d\n",
- dom_list[i].domain_name,
- sid_string_dbg(&dom_list[i].sid),
- hash));
-
- hashed_domains[hash].sid = talloc(hashed_domains, DOM_SID);
- sid_copy(hashed_domains[hash].sid, &dom_list[i].sid);
- }
-
-done:
- return nt_status;
-}
-
-/*********************************************************************
- ********************************************************************/
-
-static NTSTATUS unixids_to_sids(struct idmap_domain *dom,
- struct id_map **ids)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- int i;
-
- nt_status = be_init(dom, NULL);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if (!ids) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- for (i=0; ids[i]; i++) {
- uint32_t h_domain, h_rid;
-
- ids[i]->status = ID_UNMAPPED;
-
- separate_hashes(ids[i]->xid.id, &h_domain, &h_rid);
-
- /* Make sure the caller allocated memor for us */
-
- if (!ids[i]->sid) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* If the domain hash doesn't find a SID in the table,
- skip it */
-
- if (!hashed_domains[h_domain].sid)
- continue;
-
- sid_copy(ids[i]->sid, hashed_domains[h_domain].sid);
- sid_append_rid(ids[i]->sid, h_rid);
- ids[i]->status = ID_MAPPED;
- }
-
-done:
- return nt_status;
-}
-
-/*********************************************************************
- ********************************************************************/
-
-static NTSTATUS sids_to_unixids(struct idmap_domain *dom,
- struct id_map **ids)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- int i;
-
- nt_status = be_init(dom, NULL);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if (!ids) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- for (i=0; ids[i]; i++) {
- DOM_SID sid;
- uint32_t rid;
- uint32_t h_domain, h_rid;
-
- ids[i]->status = ID_UNMAPPED;
-
- sid_copy(&sid, ids[i]->sid);
- sid_split_rid(&sid, &rid);
-
- h_domain = hash_domain_sid(&sid);
- h_rid = hash_rid(rid);
-
- /* Check that both hashes are non-zero*/
-
- if (h_domain && h_rid) {
- ids[i]->xid.id = combine_hashes(h_domain, h_rid);
- ids[i]->status = ID_MAPPED;
- }
- }
-
-done:
- return nt_status;
-}
-
-/*********************************************************************
- ********************************************************************/
-
-static NTSTATUS be_close(struct idmap_domain *dom)
-{
- if (hashed_domains)
- talloc_free(hashed_domains);
-
- return NT_STATUS_OK;
-}
-
-/*********************************************************************
- ********************************************************************/
-
-static NTSTATUS nss_hash_init(struct nss_domain_entry *e )
-{
- return be_init(NULL, NULL);
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS nss_hash_get_info(struct nss_domain_entry *e,
- const DOM_SID *sid,
- TALLOC_CTX *ctx,
- ADS_STRUCT *ads,
- LDAPMessage *msg,
- char **homedir,
- char **shell,
- char **gecos,
- gid_t *p_gid )
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
- nt_status = nss_hash_init(e);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if (!homedir || !shell || !gecos) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- *homedir = talloc_strdup(ctx, lp_template_homedir());
- BAIL_ON_PTR_NT_ERROR(*homedir, nt_status);
-
- *shell = talloc_strdup(ctx, lp_template_shell());
- BAIL_ON_PTR_NT_ERROR(*shell, nt_status);
-
- *gecos = NULL;
-
- /* Initialize the gid so that the upper layer fills
- in the proper Windows primary group */
-
- if (*p_gid) {
- *p_gid = (gid_t)-1;
- }
-
-done:
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS nss_hash_map_to_alias(TALLOC_CTX *mem_ctx,
- const char *domain,
- const char *name,
- char **alias)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- const char *value;
-
- value = talloc_asprintf(mem_ctx, "%s\\%s", domain, name);
- BAIL_ON_PTR_NT_ERROR(value, nt_status);
-
- nt_status = mapfile_lookup_key(mem_ctx, value, alias);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS nss_hash_map_from_alias(TALLOC_CTX *mem_ctx,
- const char *domain,
- const char *alias,
- char **name)
-{
- return mapfile_lookup_value(mem_ctx, alias, name);
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS nss_hash_close(void)
-{
- return NT_STATUS_OK;
-}
-
-/*********************************************************************
- Dispatch Tables for IDMap and NssInfo Methods
-********************************************************************/
-
-static struct idmap_methods hash_idmap_methods = {
- .init = be_init,
- .unixids_to_sids = unixids_to_sids,
- .sids_to_unixids = sids_to_unixids,
- .close_fn = be_close
-};
-
-static struct nss_info_methods hash_nss_methods = {
- .init = nss_hash_init,
- .get_nss_info = nss_hash_get_info,
- .map_to_alias = nss_hash_map_to_alias,
- .map_from_alias = nss_hash_map_from_alias,
- .close_fn = nss_hash_close
-};
-
-/**********************************************************************
- Register with the idmap and idmap_nss subsystems. We have to protect
- against the idmap and nss_info interfaces being in a half-registered
- state.
- **********************************************************************/
-
-NTSTATUS idmap_hash_init(void)
-{
- static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL;
- static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL;
-
- if ( !NT_STATUS_IS_OK(idmap_status) ) {
- idmap_status = smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
- "hash", &hash_idmap_methods);
-
- if ( !NT_STATUS_IS_OK(idmap_status) ) {
- DEBUG(0,("Failed to register hash idmap plugin.\n"));
- return idmap_status;
- }
- }
-
- if ( !NT_STATUS_IS_OK(nss_status) ) {
- nss_status = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
- "hash", &hash_nss_methods);
- if ( !NT_STATUS_IS_OK(nss_status) ) {
- DEBUG(0,("Failed to register hash idmap nss plugin.\n"));
- return nss_status;
- }
- }
-
- return NT_STATUS_OK;
-}
diff --git a/source/winbindd/idmap_hash/idmap_hash.h b/source/winbindd/idmap_hash/idmap_hash.h
deleted file mode 100644
index 621520e950..0000000000
--- a/source/winbindd/idmap_hash/idmap_hash.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * lwopen.h
- *
- * Copyright (C) Gerald Carter <jerry@samba.org>
- *
- * 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
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef _LWOPEN_H
-#define _LWOPEN_H
-
-#define BAIL_ON_NTSTATUS_ERROR(x) \
- do { \
- if (!NT_STATUS_IS_OK(x)) { \
- DEBUG(10,("Failed! (%s)\n", nt_errstr(x))); \
- goto done; \
- } \
- } \
- while (0); \
-
-#define BAIL_ON_PTR_NT_ERROR(p, x) \
- do { \
- if ((p) == NULL ) { \
- DEBUG(10,("NULL pointer!\n")); \
- x = NT_STATUS_NO_MEMORY; \
- goto done; \
- } else { \
- x = NT_STATUS_OK; \
- } \
- } while (0);
-
-#define PRINT_NTSTATUS_ERROR(x, hdr, level) \
- do { \
- if (!NT_STATUS_IS_OK(x)) { \
- DEBUG(level,("Likewise Open ("hdr"): %s\n", nt_errstr(x))); \
- } \
- } while(0);
-
-
-NTSTATUS mapfile_lookup_key(TALLOC_CTX *ctx,
- const char *value,
- char **key);
-
-NTSTATUS mapfile_lookup_value(TALLOC_CTX *ctx,
- const char *key,
- char **value);
-
-#endif /* _LWOPEN_H */
diff --git a/source/winbindd/idmap_hash/mapfile.c b/source/winbindd/idmap_hash/mapfile.c
deleted file mode 100644
index 5ab1142ffe..0000000000
--- a/source/winbindd/idmap_hash/mapfile.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * mapfile.c
- *
- * Copyright (C) Gerald Carter <jerry@samba.org>
- *
- * 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
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "includes.h"
-#include "winbindd/winbindd.h"
-#include "idmap_hash.h"
-#include <stdio.h>
-
-XFILE *lw_map_file = NULL;
-
-/*********************************************************************
- ********************************************************************/
-
-static bool mapfile_open(void)
-{
- const char *mapfile_name = NULL;
-
- /* If we have an open handle, just reset it */
-
- if (lw_map_file) {
- return (x_tseek(lw_map_file, 0, SEEK_SET) == 0);
- }
-
- mapfile_name = lp_parm_const_string(-1, "idmap_hash", "name_map", NULL);
- if (!mapfile_name) {
- return false;
- }
-
- lw_map_file = x_fopen(mapfile_name, O_RDONLY, 0);
- if (!lw_map_file) {
- DEBUG(0,("can't open idmap_hash:name_map (%s). Error %s\n",
- mapfile_name, strerror(errno) ));
- return false;
- }
-
- return true;
-}
-
-/*********************************************************************
- ********************************************************************/
-
-static bool mapfile_read_line(fstring key, fstring value)
-{
- char buffer[1024];
- char *p;
- int len;
-
- if (!lw_map_file)
- return false;
-
- if ((p = x_fgets(buffer, sizeof(buffer)-1, lw_map_file)) == NULL) {
- return false;
- }
-
- /* Strip newlines and carriage returns */
-
- len = strlen_m(buffer) - 1;
- while ((buffer[len] == '\n') || (buffer[len] == '\r')) {
- buffer[len--] = '\0';
- }
-
-
- if ((p = strchr_m(buffer, '=')) == NULL ) {
- DEBUG(0,("idmap_hash: Bad line in name_map (%s)\n", buffer));
- return false;
- }
-
- *p = '\0';
- p++;
-
- fstrcpy(key, buffer);
- fstrcpy(value, p);
-
- /* Eat whitespace */
-
- if (!trim_char(key, ' ', ' '))
- return false;
-
- if (!trim_char(value, ' ', ' '))
- return false;
-
- return true;
-}
-
-/*********************************************************************
- ********************************************************************/
-
-static bool mapfile_close(void)
-{
- int ret = 0;
- if (lw_map_file) {
- ret = x_fclose(lw_map_file);
- lw_map_file = NULL;
- }
-
- return (ret == 0);
-}
-
-
-/*********************************************************************
- ********************************************************************/
-
-NTSTATUS mapfile_lookup_key(TALLOC_CTX *ctx, const char *value, char **key)
-{
- fstring r_key, r_value;
- NTSTATUS ret = NT_STATUS_NOT_FOUND;
-
- if (!mapfile_open())
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
-
- while (mapfile_read_line(r_key, r_value))
- {
- if (strequal(r_value, value)) {
- ret = NT_STATUS_OK;
-
- /* We're done once finishing this block */
- *key = talloc_strdup(ctx, r_key);
- if (!*key) {
- ret = NT_STATUS_NO_MEMORY;
- }
- break;
- }
- }
-
- mapfile_close();
-
- return ret;
-}
-
-/*********************************************************************
- ********************************************************************/
-
-NTSTATUS mapfile_lookup_value(TALLOC_CTX *ctx, const char *key, char **value)
-{
- fstring r_key, r_value;
- NTSTATUS ret = NT_STATUS_NOT_FOUND;
-
- if (!mapfile_open())
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
-
- while (mapfile_read_line(r_key, r_value))
- {
- if (strequal(r_key, key)) {
- ret = NT_STATUS_OK;
-
- /* We're done once finishing this block */
- *value = talloc_strdup(ctx, r_value);
- if (!*key) {
- ret = NT_STATUS_NO_MEMORY;
- }
- break;
- }
- }
-
- mapfile_close();
-
- return ret;
-}
diff --git a/source/winbindd/idmap_ldap.c b/source/winbindd/idmap_ldap.c
index c86a5023d0..fa80fae5d8 100644
--- a/source/winbindd/idmap_ldap.c
+++ b/source/winbindd/idmap_ldap.c
@@ -33,29 +33,6 @@
#include "smbldap.h"
-static char *idmap_fetch_secret(const char *backend, bool alloc,
- const char *domain, const char *identity)
-{
- char *tmp, *ret;
- int r;
-
- if (alloc) {
- r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend);
- } else {
- r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
- }
-
- if (r < 0)
- return NULL;
-
- strupper_m(tmp); /* make sure the key is case insensitive */
- ret = secrets_fetch_generic(tmp, identity);
-
- SAFE_FREE(tmp);
-
- return ret;
-}
-
struct idmap_ldap_context {
struct smbldap_state *smbldap_state;
char *url;
@@ -246,6 +223,7 @@ done:
static NTSTATUS idmap_ldap_alloc_init(const char *params)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ const char *range;
const char *tmp;
uid_t low_uid = 0;
uid_t high_uid = 0;
@@ -262,27 +240,50 @@ static NTSTATUS idmap_ldap_alloc_init(const char *params)
/* load ranges */
- if (!lp_idmap_uid(&low_uid, &high_uid)
- || !lp_idmap_gid(&low_gid, &high_gid)) {
- DEBUG(1, ("idmap uid or idmap gid missing\n"));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
+ idmap_alloc_ldap->low_uid = 0;
+ idmap_alloc_ldap->high_uid = 0;
+ idmap_alloc_ldap->low_gid = 0;
+ idmap_alloc_ldap->high_gid = 0;
+
+ range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL);
+ if (range && range[0]) {
+ unsigned low_id, high_id;
+
+ if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) {
+ if (low_id < high_id) {
+ idmap_alloc_ldap->low_gid = low_id;
+ idmap_alloc_ldap->low_uid = low_id;
+ idmap_alloc_ldap->high_gid = high_id;
+ idmap_alloc_ldap->high_uid = high_id;
+ } else {
+ DEBUG(1, ("ERROR: invalid idmap alloc range "
+ "[%s]", range));
+ }
+ } else {
+ DEBUG(1, ("ERROR: invalid syntax for idmap alloc "
+ "config:range [%s]", range));
+ }
}
- idmap_alloc_ldap->low_uid = low_uid;
- idmap_alloc_ldap->high_uid = high_uid;
- idmap_alloc_ldap->low_gid = low_gid;
- idmap_alloc_ldap->high_gid= high_gid;
+ if (lp_idmap_uid(&low_uid, &high_uid)) {
+ idmap_alloc_ldap->low_uid = low_uid;
+ idmap_alloc_ldap->high_uid = high_uid;
+ }
+
+ if (lp_idmap_gid(&low_gid, &high_gid)) {
+ idmap_alloc_ldap->low_gid = low_gid;
+ idmap_alloc_ldap->high_gid= high_gid;
+ }
if (idmap_alloc_ldap->high_uid <= idmap_alloc_ldap->low_uid) {
- DEBUG(1, ("idmap uid range invalid\n"));
+ DEBUG(1, ("idmap uid range missing or invalid\n"));
DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (idmap_alloc_ldap->high_gid <= idmap_alloc_ldap->low_gid) {
- DEBUG(1, ("idmap gid range invalid\n"));
+ DEBUG(1, ("idmap gid range missing or invalid\n"));
DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
@@ -759,8 +760,7 @@ static int idmap_ldap_close_destructor(struct idmap_ldap_context *ctx)
Initialise idmap database.
********************************/
-static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom,
- const char *params)
+static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
{
NTSTATUS ret;
struct idmap_ldap_context *ctx = NULL;
@@ -798,9 +798,9 @@ static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom,
}
}
- if (params != NULL) {
+ if (dom->params && *(dom->params)) {
/* assume location is the only parameter */
- ctx->url = talloc_strdup(ctx, params);
+ ctx->url = talloc_strdup(ctx, dom->params);
} else {
tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
@@ -848,6 +848,7 @@ static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom,
talloc_set_destructor(ctx, idmap_ldap_close_destructor);
dom->private_data = ctx;
+ dom->initialized = True;
talloc_free(config_option);
return NT_STATUS_OK;
@@ -908,6 +909,14 @@ static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom,
return NT_STATUS_FILE_IS_OFFLINE;
}
+ /* Initilization my have been deferred because we were offline */
+ if ( ! dom->initialized) {
+ ret = idmap_ldap_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
memctx = talloc_new(ctx);
@@ -1129,6 +1138,14 @@ static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
return NT_STATUS_FILE_IS_OFFLINE;
}
+ /* Initilization my have been deferred because we were offline */
+ if ( ! dom->initialized) {
+ ret = idmap_ldap_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
memctx = talloc_new(ctx);
@@ -1333,6 +1350,14 @@ static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
return NT_STATUS_FILE_IS_OFFLINE;
}
+ /* Initilization my have been deferred because we were offline */
+ if ( ! dom->initialized) {
+ ret = idmap_ldap_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
switch(map->xid.type) {
@@ -1457,13 +1482,12 @@ static struct idmap_alloc_methods idmap_ldap_alloc_methods = {
/* .dump_data = TODO */
};
-static NTSTATUS idmap_alloc_ldap_init(void)
+NTSTATUS idmap_alloc_ldap_init(void)
{
return smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "ldap",
&idmap_ldap_alloc_methods);
}
-NTSTATUS idmap_ldap_init(void);
NTSTATUS idmap_ldap_init(void)
{
NTSTATUS ret;
diff --git a/source/winbindd/idmap_nss.c b/source/winbindd/idmap_nss.c
index 156fdc7cc9..e4acd9ce65 100644
--- a/source/winbindd/idmap_nss.c
+++ b/source/winbindd/idmap_nss.c
@@ -29,9 +29,9 @@
Initialise idmap database.
*****************************/
-static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom,
- const char *params)
+static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom)
{
+ dom->initialized = True;
return NT_STATUS_OK;
}
@@ -44,6 +44,10 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
TALLOC_CTX *ctx;
int i;
+ if (! dom->initialized) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
ctx = talloc_new(dom);
if ( ! ctx) {
DEBUG(0, ("Out of memory!\n"));
@@ -130,6 +134,10 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
TALLOC_CTX *ctx;
int i;
+ if (! dom->initialized) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
ctx = talloc_new(dom);
if ( ! ctx) {
DEBUG(0, ("Out of memory!\n"));
diff --git a/source/winbindd/idmap_passdb.c b/source/winbindd/idmap_passdb.c
index 4dcf74416c..17afd71ab8 100644
--- a/source/winbindd/idmap_passdb.c
+++ b/source/winbindd/idmap_passdb.c
@@ -28,8 +28,9 @@
Initialise idmap database.
*****************************/
-static NTSTATUS idmap_pdb_init(struct idmap_domain *dom, const char *params)
+static NTSTATUS idmap_pdb_init(struct idmap_domain *dom)
{
+ dom->initialized = True;
return NT_STATUS_OK;
}
@@ -41,6 +42,10 @@ static NTSTATUS idmap_pdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
{
int i;
+ if (! dom->initialized) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
for (i = 0; ids[i]; i++) {
/* unmapped by default */
@@ -73,6 +78,10 @@ static NTSTATUS idmap_pdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma
{
int i;
+ if (! dom->initialized) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
for (i = 0; ids[i]; i++) {
enum lsa_SidType type;
union unid_t id;
diff --git a/source/winbindd/idmap_rid.c b/source/winbindd/idmap_rid.c
index 9d1898708c..f1cd77853c 100644
--- a/source/winbindd/idmap_rid.c
+++ b/source/winbindd/idmap_rid.c
@@ -36,8 +36,7 @@ struct idmap_rid_context {
we support multiple domains in the new idmap
*****************************************************************************/
-static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom,
- const char *params)
+static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom)
{
NTSTATUS ret;
struct idmap_rid_context *ctx;
@@ -96,6 +95,7 @@ static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom,
ctx->domain_name = talloc_strdup( ctx, dom->name );
dom->private_data = ctx;
+ dom->initialized = True;
talloc_free(config_option);
return NT_STATUS_OK;
@@ -171,6 +171,14 @@ static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
+ /* Initilization my have been deferred because of an error, retry or fail */
+ if ( ! dom->initialized) {
+ ret = idmap_rid_initialize(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
ctx = talloc_new(dom);
@@ -205,6 +213,14 @@ static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
+ /* Initilization my have been deferred because of an error, retry or fail */
+ if ( ! dom->initialized) {
+ ret = idmap_rid_initialize(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
ctx = talloc_new(dom);
diff --git a/source/winbindd/idmap_tdb.c b/source/winbindd/idmap_tdb.c
index 9e66eed0c8..e5f605361b 100644
--- a/source/winbindd/idmap_tdb.c
+++ b/source/winbindd/idmap_tdb.c
@@ -313,11 +313,11 @@ static NTSTATUS idmap_tdb_alloc_init( const char *params )
{
NTSTATUS ret;
TALLOC_CTX *ctx;
+ const char *range;
uid_t low_uid = 0;
uid_t high_uid = 0;
gid_t low_gid = 0;
gid_t high_gid = 0;
- uint32_t low_id;
/* use our own context here */
ctx = talloc_new(NULL);
@@ -335,47 +335,67 @@ static NTSTATUS idmap_tdb_alloc_init( const char *params )
talloc_free(ctx);
/* load ranges */
+ idmap_tdb_state.low_uid = 0;
+ idmap_tdb_state.high_uid = 0;
+ idmap_tdb_state.low_gid = 0;
+ idmap_tdb_state.high_gid = 0;
+
+ range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL);
+ if (range && range[0]) {
+ unsigned low_id, high_id;
+
+ if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) {
+ if (low_id < high_id) {
+ idmap_tdb_state.low_gid = idmap_tdb_state.low_uid = low_id;
+ idmap_tdb_state.high_gid = idmap_tdb_state.high_uid = high_id;
+ } else {
+ DEBUG(1, ("ERROR: invalid idmap alloc range [%s]", range));
+ }
+ } else {
+ DEBUG(1, ("ERROR: invalid syntax for idmap alloc config:range [%s]", range));
+ }
+ }
- if (!lp_idmap_uid(&low_uid, &high_uid)
- || !lp_idmap_gid(&low_gid, &high_gid)) {
- DEBUG(1, ("idmap uid or idmap gid missing\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ /* Create high water marks for group and user id */
+ if (lp_idmap_uid(&low_uid, &high_uid)) {
+ idmap_tdb_state.low_uid = low_uid;
+ idmap_tdb_state.high_uid = high_uid;
}
- idmap_tdb_state.low_uid = low_uid;
- idmap_tdb_state.high_uid = high_uid;
- idmap_tdb_state.low_gid = low_gid;
- idmap_tdb_state.high_gid = high_gid;
+ if (lp_idmap_gid(&low_gid, &high_gid)) {
+ idmap_tdb_state.low_gid = low_gid;
+ idmap_tdb_state.high_gid = high_gid;
+ }
if (idmap_tdb_state.high_uid <= idmap_tdb_state.low_uid) {
DEBUG(1, ("idmap uid range missing or invalid\n"));
DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
return NT_STATUS_UNSUCCESSFUL;
+ } else {
+ uint32 low_id;
+
+ if (((low_id = tdb_fetch_int32(idmap_alloc_tdb, HWM_USER)) == -1) ||
+ (low_id < idmap_tdb_state.low_uid)) {
+ if (tdb_store_int32(idmap_alloc_tdb, HWM_USER, idmap_tdb_state.low_uid) == -1) {
+ DEBUG(0, ("Unable to initialise user hwm in idmap database\n"));
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+ }
}
if (idmap_tdb_state.high_gid <= idmap_tdb_state.low_gid) {
DEBUG(1, ("idmap gid range missing or invalid\n"));
DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (((low_id = tdb_fetch_int32(idmap_alloc_tdb, HWM_USER)) == -1) ||
- (low_id < idmap_tdb_state.low_uid)) {
- if (tdb_store_int32(idmap_alloc_tdb, HWM_USER,
- idmap_tdb_state.low_uid) == -1) {
- DEBUG(0, ("Unable to initialise user hwm in idmap "
- "database\n"));
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
- }
-
- if (((low_id = tdb_fetch_int32(idmap_alloc_tdb, HWM_GROUP)) == -1) ||
- (low_id < idmap_tdb_state.low_gid)) {
- if (tdb_store_int32(idmap_alloc_tdb, HWM_GROUP,
- idmap_tdb_state.low_gid) == -1) {
- DEBUG(0, ("Unable to initialise group hwm in idmap "
- "database\n"));
- return NT_STATUS_INTERNAL_DB_ERROR;
+ } else {
+ uint32 low_id;
+
+ if (((low_id = tdb_fetch_int32(idmap_alloc_tdb, HWM_GROUP)) == -1) ||
+ (low_id < idmap_tdb_state.low_gid)) {
+ if (tdb_store_int32(idmap_alloc_tdb, HWM_GROUP, idmap_tdb_state.low_gid) == -1) {
+ DEBUG(0, ("Unable to initialise group hwm in idmap database\n"));
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
}
}
@@ -565,7 +585,7 @@ struct idmap_tdb_context {
Initialise idmap database.
*****************************/
-static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params)
+static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom)
{
NTSTATUS ret;
struct idmap_tdb_context *ctx;
@@ -599,6 +619,7 @@ static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params)
}
dom->private_data = ctx;
+ dom->initialized = True;
talloc_free(config_option);
return NT_STATUS_OK;
@@ -753,6 +774,14 @@ static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
for (i = 0; ids[i]; i++) {
@@ -791,6 +820,14 @@ static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
for (i = 0; ids[i]; i++) {
@@ -831,6 +868,14 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
char *ksidstr, *kidstr;
fstring tmp;
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
if (!map || !map->sid) {
return NT_STATUS_INVALID_PARAMETER;
}
@@ -938,6 +983,14 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
char *ksidstr, *kidstr;
fstring tmp;
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
if (!map || !map->sid) {
return NT_STATUS_INVALID_PARAMETER;
}
@@ -1118,6 +1171,14 @@ static NTSTATUS idmap_tdb_dump_data(struct idmap_domain *dom, struct id_map **ma
struct dump_data *data;
NTSTATUS ret = NT_STATUS_OK;
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
data = TALLOC_ZERO_P(ctx, struct dump_data);
@@ -1168,8 +1229,6 @@ NTSTATUS idmap_tdb_init(void)
{
NTSTATUS ret;
- DEBUG(10, ("calling idmap_tdb_init\n"));
-
/* FIXME: bad hack to actually register also the alloc_tdb module without changining configure.in */
ret = idmap_alloc_tdb_init();
if (! NT_STATUS_IS_OK(ret)) {
diff --git a/source/winbindd/idmap_tdb2.c b/source/winbindd/idmap_tdb2.c
index 8bde963c60..ab89e615f7 100644
--- a/source/winbindd/idmap_tdb2.c
+++ b/source/winbindd/idmap_tdb2.c
@@ -3,8 +3,9 @@
idmap TDB2 backend, used for clustered Samba setups.
- This uses dbwrap to access tdb files. The location can be set
- using tdb:idmap2.tdb =" in smb.conf
+ This uses 2 tdb files. One is permanent, and is in shared storage
+ on the cluster (using "tdb:idmap2.tdb =" in smb.conf). The other is a
+ temporary cache tdb on local storage.
Copyright (C) Andrew Tridgell 2007
@@ -49,19 +50,46 @@ static struct idmap_tdb2_state {
+/* tdb context for the local cache tdb */
+static TDB_CONTEXT *idmap_tdb2_tmp;
+
/* handle to the permanent tdb */
-static struct db_context *idmap_tdb2;
+static struct db_context *idmap_tdb2_perm;
+
+/*
+ open the cache tdb
+ */
+static NTSTATUS idmap_tdb2_open_cache_db(void)
+{
+ const char *db_path;
+
+ if (idmap_tdb2_tmp) {
+ /* its already open */
+ return NT_STATUS_OK;
+ }
+
+ db_path = lock_path("idmap2_cache.tdb");
+
+ /* Open idmap repository */
+ if (!(idmap_tdb2_tmp = tdb_open_log(db_path, 0, TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0644))) {
+ DEBUG(0, ("Unable to open cache idmap database '%s'\n", db_path));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return NT_STATUS_OK;
+}
+
static NTSTATUS idmap_tdb2_alloc_load(void);
/*
open the permanent tdb
*/
-static NTSTATUS idmap_tdb2_open_db(void)
+static NTSTATUS idmap_tdb2_open_perm_db(void)
{
char *db_path;
- if (idmap_tdb2) {
+ if (idmap_tdb2_perm) {
/* its already open */
return NT_STATUS_OK;
}
@@ -75,11 +103,12 @@ static NTSTATUS idmap_tdb2_open_db(void)
NT_STATUS_HAVE_NO_MEMORY(db_path);
/* Open idmap repository */
- idmap_tdb2 = db_open(NULL, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
+ idmap_tdb2_perm = db_open(NULL, db_path, 0, TDB_DEFAULT,
+ O_RDWR|O_CREAT, 0644);
TALLOC_FREE(db_path);
- if (idmap_tdb2 == NULL) {
- DEBUG(0, ("Unable to open idmap_tdb2 database '%s'\n",
+ if (idmap_tdb2_perm == NULL) {
+ DEBUG(0, ("Unable to open permanent idmap database '%s'\n",
db_path));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -94,50 +123,67 @@ static NTSTATUS idmap_tdb2_open_db(void)
*/
static NTSTATUS idmap_tdb2_alloc_load(void)
{
+ const char *range;
uid_t low_uid = 0;
uid_t high_uid = 0;
gid_t low_gid = 0;
gid_t high_gid = 0;
- uint32 low_id;
+
+ /* load ranges */
+ idmap_tdb2_state.low_uid = 0;
+ idmap_tdb2_state.high_uid = 0;
+ idmap_tdb2_state.low_gid = 0;
+ idmap_tdb2_state.high_gid = 0;
/* see if a idmap script is configured */
- idmap_tdb2_state.idmap_script = lp_parm_const_string(-1, "idmap",
- "script", NULL);
+ idmap_tdb2_state.idmap_script = lp_parm_const_string(-1, "idmap", "script", NULL);
if (idmap_tdb2_state.idmap_script) {
- DEBUG(1, ("using idmap script '%s'\n",
- idmap_tdb2_state.idmap_script));
+ DEBUG(1, ("using idmap script '%s'\n", idmap_tdb2_state.idmap_script));
+ }
+
+ range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL);
+ if (range && range[0]) {
+ unsigned low_id, high_id;
+ if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) {
+ if (low_id < high_id) {
+ idmap_tdb2_state.low_gid = idmap_tdb2_state.low_uid = low_id;
+ idmap_tdb2_state.high_gid = idmap_tdb2_state.high_uid = high_id;
+ } else {
+ DEBUG(1, ("ERROR: invalid idmap alloc range [%s]", range));
+ }
+ } else {
+ DEBUG(1, ("ERROR: invalid syntax for idmap alloc config:range [%s]", range));
+ }
}
- /* load ranges */
-
/* Create high water marks for group and user id */
- if (!lp_idmap_uid(&low_uid, &high_uid)
- || !lp_idmap_gid(&low_gid, &high_gid)) {
- DEBUG(1, ("idmap uid or idmap gid missing\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ if (lp_idmap_uid(&low_uid, &high_uid)) {
+ idmap_tdb2_state.low_uid = low_uid;
+ idmap_tdb2_state.high_uid = high_uid;
}
- idmap_tdb2_state.low_uid = low_uid;
- idmap_tdb2_state.high_uid = high_uid;
- idmap_tdb2_state.low_gid = low_gid;
- idmap_tdb2_state.high_gid = high_gid;
+ if (lp_idmap_gid(&low_gid, &high_gid)) {
+ idmap_tdb2_state.low_gid = low_gid;
+ idmap_tdb2_state.high_gid = high_gid;
+ }
if (idmap_tdb2_state.high_uid <= idmap_tdb2_state.low_uid) {
DEBUG(1, ("idmap uid range missing or invalid\n"));
DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (((low_id = dbwrap_fetch_int32(idmap_tdb2,
- HWM_USER)) == -1) ||
- (low_id < idmap_tdb2_state.low_uid)) {
- if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32(
- idmap_tdb2, HWM_USER,
- idmap_tdb2_state.low_uid))) {
- DEBUG(0, ("Unable to initialise user hwm in idmap "
- "database\n"));
- return NT_STATUS_INTERNAL_DB_ERROR;
+ } else {
+ uint32 low_id;
+
+ if (((low_id = dbwrap_fetch_int32(idmap_tdb2_perm,
+ HWM_USER)) == -1) ||
+ (low_id < idmap_tdb2_state.low_uid)) {
+ if (dbwrap_store_int32(
+ idmap_tdb2_perm, HWM_USER,
+ idmap_tdb2_state.low_uid) == -1) {
+ DEBUG(0, ("Unable to initialise user hwm in idmap database\n"));
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
}
}
@@ -145,17 +191,18 @@ static NTSTATUS idmap_tdb2_alloc_load(void)
DEBUG(1, ("idmap gid range missing or invalid\n"));
DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (((low_id = dbwrap_fetch_int32(idmap_tdb2,
- HWM_GROUP)) == -1) ||
- (low_id < idmap_tdb2_state.low_gid)) {
- if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32(
- idmap_tdb2, HWM_GROUP,
- idmap_tdb2_state.low_gid))) {
- DEBUG(0, ("Unable to initialise group hwm in idmap "
- "database\n"));
- return NT_STATUS_INTERNAL_DB_ERROR;
+ } else {
+ uint32 low_id;
+
+ if (((low_id = dbwrap_fetch_int32(idmap_tdb2_perm,
+ HWM_GROUP)) == -1) ||
+ (low_id < idmap_tdb2_state.low_gid)) {
+ if (dbwrap_store_int32(
+ idmap_tdb2_perm, HWM_GROUP,
+ idmap_tdb2_state.low_gid) == -1) {
+ DEBUG(0, ("Unable to initialise group hwm in idmap database\n"));
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
}
}
@@ -185,10 +232,9 @@ static NTSTATUS idmap_tdb2_allocate_id(struct unixid *xid)
const char *hwmtype;
uint32_t high_hwm;
uint32_t hwm;
- int res;
NTSTATUS status;
- status = idmap_tdb2_open_db();
+ status = idmap_tdb2_open_perm_db();
NT_STATUS_NOT_OK_RETURN(status);
/* Get current high water mark */
@@ -211,14 +257,7 @@ static NTSTATUS idmap_tdb2_allocate_id(struct unixid *xid)
return NT_STATUS_INVALID_PARAMETER;
}
- res = idmap_tdb2->transaction_start(idmap_tdb2);
- if (res != 0) {
- DEBUG(1,(__location__ " Failed to start transaction\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if ((hwm = dbwrap_fetch_int32(idmap_tdb2, hwmkey)) == -1) {
- idmap_tdb2->transaction_cancel(idmap_tdb2);
+ if ((hwm = dbwrap_fetch_int32(idmap_tdb2_perm, hwmkey)) == -1) {
return NT_STATUS_INTERNAL_DB_ERROR;
}
@@ -226,15 +265,13 @@ static NTSTATUS idmap_tdb2_allocate_id(struct unixid *xid)
if (hwm > high_hwm) {
DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
hwmtype, (unsigned long)high_hwm));
- idmap_tdb2->transaction_cancel(idmap_tdb2);
return NT_STATUS_UNSUCCESSFUL;
}
/* fetch a new id and increment it */
- ret = dbwrap_change_uint32_atomic(idmap_tdb2, hwmkey, &hwm, 1);
+ ret = dbwrap_change_uint32_atomic(idmap_tdb2_perm, hwmkey, &hwm, 1);
if (ret == -1) {
DEBUG(1, ("Fatal error while fetching a new %s value\n!", hwmtype));
- idmap_tdb2->transaction_cancel(idmap_tdb2);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -242,13 +279,6 @@ static NTSTATUS idmap_tdb2_allocate_id(struct unixid *xid)
if (hwm > high_hwm) {
DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
hwmtype, (unsigned long)high_hwm));
- idmap_tdb2->transaction_cancel(idmap_tdb2);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- res = idmap_tdb2->transaction_commit(idmap_tdb2);
- if (res != 0) {
- DEBUG(1,(__location__ " Failed to commit transaction\n"));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -267,10 +297,6 @@ static NTSTATUS idmap_tdb2_get_hwm(struct unixid *xid)
const char *hwmtype;
uint32_t hwm;
uint32_t high_hwm;
- NTSTATUS status;
-
- status = idmap_tdb2_open_db();
- NT_STATUS_NOT_OK_RETURN(status);
/* Get current high water mark */
switch (xid->type) {
@@ -291,7 +317,7 @@ static NTSTATUS idmap_tdb2_get_hwm(struct unixid *xid)
return NT_STATUS_INVALID_PARAMETER;
}
- if ((hwm = dbwrap_fetch_int32(idmap_tdb2, hwmkey)) == -1) {
+ if ((hwm = dbwrap_fetch_int32(idmap_tdb2_perm, hwmkey)) == -1) {
return NT_STATUS_INTERNAL_DB_ERROR;
}
@@ -335,10 +361,77 @@ struct idmap_tdb2_context {
};
/*
+ try fetching from the cache tdb, and if that fails then
+ fetch from the permanent tdb
+ */
+static TDB_DATA tdb2_fetch_bystring(TALLOC_CTX *mem_ctx, const char *keystr)
+{
+ TDB_DATA ret;
+ NTSTATUS status;
+
+ ret = tdb_fetch_bystring(idmap_tdb2_tmp, keystr);
+ if (ret.dptr != NULL) {
+ /* got it from cache */
+ unsigned char *tmp;
+
+ tmp = (unsigned char *)talloc_memdup(mem_ctx, ret.dptr,
+ ret.dsize);
+ SAFE_FREE(ret.dptr);
+ ret.dptr = tmp;
+
+ if (ret.dptr == NULL) {
+ return make_tdb_data(NULL, 0);
+ }
+ return ret;
+ }
+
+ status = idmap_tdb2_open_perm_db();
+ if (!NT_STATUS_IS_OK(status)) {
+ return ret;
+ }
+
+ /* fetch from the permanent tdb */
+ return dbwrap_fetch_bystring(idmap_tdb2_perm, mem_ctx, keystr);
+}
+
+/*
+ store into both databases
+ */
+static NTSTATUS tdb2_store_bystring(const char *keystr, TDB_DATA data, int flags)
+{
+ NTSTATUS ret;
+ NTSTATUS status = idmap_tdb2_open_perm_db();
+ if (!NT_STATUS_IS_OK(status)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ ret = dbwrap_store_bystring(idmap_tdb2_perm, keystr, data, flags);
+ if (!NT_STATUS_IS_OK(ret)) {
+ ret = tdb_store_bystring(idmap_tdb2_tmp, keystr, data, flags) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ }
+ return ret;
+}
+
+/*
+ delete from both databases
+ */
+static NTSTATUS tdb2_delete_bystring(const char *keystr)
+{
+ NTSTATUS ret;
+ NTSTATUS status = idmap_tdb2_open_perm_db();
+ if (!NT_STATUS_IS_OK(status)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ ret = dbwrap_delete_bystring(idmap_tdb2_perm, keystr);
+ if (!NT_STATUS_IS_OK(ret)) {
+ ret = tdb_delete_bystring(idmap_tdb2_tmp, keystr) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ }
+ return ret;
+}
+
+/*
Initialise idmap database.
*/
-static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom,
- const char *params)
+static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom)
{
NTSTATUS ret;
struct idmap_tdb2_context *ctx;
@@ -346,7 +439,7 @@ static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom,
const char *range;
NTSTATUS status;
- status = idmap_tdb2_open_db();
+ status = idmap_tdb2_open_cache_db();
NT_STATUS_NOT_OK_RETURN(status);
ctx = talloc(dom, struct idmap_tdb2_context);
@@ -371,6 +464,7 @@ static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom,
}
dom->private_data = ctx;
+ dom->initialized = True;
talloc_free(config_option);
return NT_STATUS_OK;
@@ -458,10 +552,6 @@ static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_tdb2_context *ctx, struct id_m
NTSTATUS ret;
TDB_DATA data;
char *keystr;
- NTSTATUS status;
-
- status = idmap_tdb2_open_db();
- NT_STATUS_NOT_OK_RETURN(status);
if (!ctx || !map) {
return NT_STATUS_INVALID_PARAMETER;
@@ -502,7 +592,7 @@ static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_tdb2_context *ctx, struct id_m
DEBUG(10,("Fetching record %s\n", keystr));
/* Check if the mapping exists */
- data = dbwrap_fetch_bystring(idmap_tdb2, keystr, keystr);
+ data = tdb2_fetch_bystring(keystr, keystr);
if (!data.dptr) {
fstring sidstr;
@@ -522,10 +612,10 @@ static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_tdb2_context *ctx, struct id_m
if (sid_to_fstring(sidstr, map->sid)) {
/* both forward and reverse mappings */
- dbwrap_store_bystring(idmap_tdb2, keystr,
+ tdb2_store_bystring(keystr,
string_term_tdb_data(sidstr),
TDB_REPLACE);
- dbwrap_store_bystring(idmap_tdb2, sidstr,
+ tdb2_store_bystring(sidstr,
string_term_tdb_data(keystr),
TDB_REPLACE);
}
@@ -557,10 +647,6 @@ static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_tdb2_context *ctx, struct id_m
TDB_DATA data;
char *keystr;
unsigned long rec_id = 0;
- NTSTATUS status;
-
- status = idmap_tdb2_open_db();
- NT_STATUS_NOT_OK_RETURN(status);
if ((keystr = sid_string_talloc(ctx, map->sid)) == NULL) {
DEBUG(0, ("Out of memory!\n"));
@@ -571,7 +657,7 @@ static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_tdb2_context *ctx, struct id_m
DEBUG(10,("Fetching record %s\n", keystr));
/* Check if sid is present in database */
- data = dbwrap_fetch_bystring(idmap_tdb2, keystr, keystr);
+ data = tdb2_fetch_bystring(keystr, keystr);
if (!data.dptr) {
fstring idstr;
@@ -592,9 +678,9 @@ static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_tdb2_context *ctx, struct id_m
map->xid.type == ID_TYPE_UID?'U':'G',
(unsigned long)map->xid.id);
/* store both forward and reverse mappings */
- dbwrap_store_bystring(idmap_tdb2, keystr, string_term_tdb_data(idstr),
+ tdb2_store_bystring(keystr, string_term_tdb_data(idstr),
TDB_REPLACE);
- dbwrap_store_bystring(idmap_tdb2, idstr, string_term_tdb_data(keystr),
+ tdb2_store_bystring(idstr, string_term_tdb_data(keystr),
TDB_REPLACE);
goto done;
}
@@ -639,6 +725,14 @@ static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_m
NTSTATUS ret;
int i;
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb2_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
for (i = 0; ids[i]; i++) {
@@ -676,6 +770,14 @@ static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_m
NTSTATUS ret;
int i;
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb2_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
for (i = 0; ids[i]; i++) {
@@ -714,14 +816,23 @@ static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id
NTSTATUS ret;
TDB_DATA data;
char *ksidstr, *kidstr;
- int res;
- bool started_transaction = false;
+ struct db_record *update_lock = NULL;
+ struct db_record *rec = NULL;
+
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb2_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
if (!map || !map->sid) {
return NT_STATUS_INVALID_PARAMETER;
}
ksidstr = kidstr = NULL;
+ data.dptr = NULL;
/* TODO: should we filter a set_mapping using low/high filters ? */
@@ -756,42 +867,78 @@ static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id
DEBUG(10, ("Storing %s <-> %s map\n", ksidstr, kidstr));
- res = idmap_tdb2->transaction_start(idmap_tdb2);
- if (res != 0) {
- DEBUG(1,(__location__ " Failed to start transaction\n"));
+ /*
+ * Get us the update lock. This is necessary to get the lock orders
+ * right, we need to deal with two records under a lock.
+ */
+
+ if (!(update_lock = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, ctx,
+ string_term_tdb_data("UPDATELOCK")))) {
+ DEBUG(10,("Failed to lock record %s\n", ksidstr));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- started_transaction = true;
-
- /* check wheter sid mapping is already present in db */
- data = dbwrap_fetch_bystring(idmap_tdb2, ksidstr, ksidstr);
- if (data.dptr) {
- ret = NT_STATUS_OBJECT_NAME_COLLISION;
- goto done;
+ /*
+ * *DELETE* previous mappings if any. *
+ */
+
+ /* First delete indexed on SID */
+
+ if (((rec = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock,
+ string_term_tdb_data(ksidstr))) != NULL)
+ && (rec->value.dsize != 0)) {
+ struct db_record *rec2;
+
+ if ((rec2 = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock, rec->value))
+ != NULL) {
+ rec2->delete_rec(rec2);
+ TALLOC_FREE(rec2);
+ }
+
+ rec->delete_rec(rec);
+
+ tdb_delete(idmap_tdb2_tmp, rec->key);
+ tdb_delete(idmap_tdb2_tmp, rec->value);
}
+ TALLOC_FREE(rec);
- ret = dbwrap_store_bystring(idmap_tdb2, ksidstr, string_term_tdb_data(kidstr),
- TDB_INSERT);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(0, ("Error storing SID -> ID: %s\n", nt_errstr(ret)));
- goto done;
+ /* Now delete indexed on unix ID */
+
+ if (((rec = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock,
+ string_term_tdb_data(kidstr))) != NULL)
+ && (rec->value.dsize != 0)) {
+ struct db_record *rec2;
+
+ if ((rec2 = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock, rec->value))
+ != NULL) {
+ rec2->delete_rec(rec2);
+ TALLOC_FREE(rec2);
+ }
+
+ rec->delete_rec(rec);
+
+ tdb_delete(idmap_tdb2_tmp, rec->key);
+ tdb_delete(idmap_tdb2_tmp, rec->value);
}
- ret = dbwrap_store_bystring(idmap_tdb2, kidstr, string_term_tdb_data(ksidstr),
- TDB_INSERT);
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(0, ("Error storing ID -> SID: %s\n", nt_errstr(ret)));
- /* try to remove the previous stored SID -> ID map */
- dbwrap_delete_bystring(idmap_tdb2, ksidstr);
+ TALLOC_FREE(rec);
+
+ if (!NT_STATUS_IS_OK(tdb2_store_bystring(ksidstr, string_term_tdb_data(kidstr),
+ TDB_INSERT))) {
+ DEBUG(0, ("Error storing SID -> ID\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
-
- started_transaction = false;
-
- res = idmap_tdb2->transaction_commit(idmap_tdb2);
- if (res != 0) {
- DEBUG(1,(__location__ " Failed to commit transaction\n"));
+ if (!NT_STATUS_IS_OK(tdb2_store_bystring(kidstr, string_term_tdb_data(ksidstr),
+ TDB_INSERT))) {
+ DEBUG(0, ("Error storing ID -> SID\n"));
+ /* try to remove the previous stored SID -> ID map */
+ tdb2_delete_bystring(ksidstr);
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -800,11 +947,10 @@ static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id
ret = NT_STATUS_OK;
done:
- if (started_transaction) {
- idmap_tdb2->transaction_cancel(idmap_tdb2);
- }
talloc_free(ksidstr);
talloc_free(kidstr);
+ SAFE_FREE(data.dptr);
+ TALLOC_FREE(update_lock);
return ret;
}
diff --git a/source/winbindd/idmap_util.c b/source/winbindd/idmap_util.c
index 9f876618be..0d24070dd6 100644
--- a/source/winbindd/idmap_util.c
+++ b/source/winbindd/idmap_util.c
@@ -27,50 +27,32 @@
If mapping is not possible returns an error.
*****************************************************************/
-NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID *sid, uid_t uid)
+NTSTATUS idmap_uid_to_sid(DOM_SID *sid, uid_t uid)
{
NTSTATUS ret;
struct id_map map;
- bool expired;
+ struct id_map *maps[2];
DEBUG(10,("uid = [%lu]\n", (unsigned long)uid));
- if (idmap_cache_find_uid2sid(uid, sid, &expired)) {
- DEBUG(10, ("idmap_cache_find_uid2sid found %d%s\n", uid,
- expired ? " (expired)": ""));
- if (expired && idmap_is_online()) {
- DEBUG(10, ("revalidating expired entry\n"));
- goto backend;
- }
- if (is_null_sid(sid)) {
- DEBUG(10, ("Returning negative cache entry\n"));
- return NT_STATUS_NONE_MAPPED;
- }
- DEBUG(10, ("Returning positive cache entry\n"));
- return NT_STATUS_OK;
- }
-
-backend:
map.sid = sid;
map.xid.type = ID_TYPE_UID;
map.xid.id = uid;
- ret = idmap_backends_unixid_to_sid(domname, &map);
+ maps[0] = &map;
+ maps[1] = NULL;
+
+ ret = idmap_unixids_to_sids(maps);
if ( ! NT_STATUS_IS_OK(ret)) {
DEBUG(10, ("error mapping uid [%lu]\n", (unsigned long)uid));
return ret;
}
if (map.status != ID_MAPPED) {
- struct dom_sid null_sid;
- ZERO_STRUCT(null_sid);
- idmap_cache_set_sid2uid(&null_sid, uid);
DEBUG(10, ("uid [%lu] not mapped\n", (unsigned long)uid));
return NT_STATUS_NONE_MAPPED;
}
- idmap_cache_set_sid2uid(sid, uid);
-
return NT_STATUS_OK;
}
@@ -79,50 +61,32 @@ backend:
If mapping is not possible returns an error.
*****************************************************************/
-NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid)
+NTSTATUS idmap_gid_to_sid(DOM_SID *sid, gid_t gid)
{
NTSTATUS ret;
struct id_map map;
- bool expired;
+ struct id_map *maps[2];
DEBUG(10,("gid = [%lu]\n", (unsigned long)gid));
- if (idmap_cache_find_gid2sid(gid, sid, &expired)) {
- DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n", gid,
- expired ? " (expired)": ""));
- if (expired && idmap_is_online()) {
- DEBUG(10, ("revalidating expired entry\n"));
- goto backend;
- }
- if (is_null_sid(sid)) {
- DEBUG(10, ("Returning negative cache entry\n"));
- return NT_STATUS_NONE_MAPPED;
- }
- DEBUG(10, ("Returning positive cache entry\n"));
- return NT_STATUS_OK;
- }
-
-backend:
map.sid = sid;
map.xid.type = ID_TYPE_GID;
map.xid.id = gid;
- ret = idmap_backends_unixid_to_sid(domname, &map);
+ maps[0] = &map;
+ maps[1] = NULL;
+
+ ret = idmap_unixids_to_sids(maps);
if ( ! NT_STATUS_IS_OK(ret)) {
DEBUG(10, ("error mapping gid [%lu]\n", (unsigned long)gid));
return ret;
}
if (map.status != ID_MAPPED) {
- struct dom_sid null_sid;
- ZERO_STRUCT(null_sid);
- idmap_cache_set_sid2uid(&null_sid, gid);
DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid));
return NT_STATUS_NONE_MAPPED;
}
- idmap_cache_set_sid2gid(sid, gid);
-
return NT_STATUS_OK;
}
@@ -131,70 +95,38 @@ backend:
If mapping is not possible or SID maps to a GID returns an error.
*****************************************************************/
-NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID *sid, uid_t *uid)
+NTSTATUS idmap_sid_to_uid(DOM_SID *sid, uid_t *uid)
{
NTSTATUS ret;
struct id_map map;
- bool expired;
+ struct id_map *maps[2];
DEBUG(10,("idmap_sid_to_uid: sid = [%s]\n", sid_string_dbg(sid)));
- if (idmap_cache_find_sid2uid(sid, uid, &expired)) {
- DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n",
- (int)(*uid), expired ? " (expired)": ""));
- if (expired && idmap_is_online()) {
- DEBUG(10, ("revalidating expired entry\n"));
- goto backend;
- }
- if ((*uid) == -1) {
- DEBUG(10, ("Returning negative cache entry\n"));
- return NT_STATUS_NONE_MAPPED;
- }
- DEBUG(10, ("Returning positive cache entry\n"));
- return NT_STATUS_OK;
- }
-
-backend:
map.sid = sid;
map.xid.type = ID_TYPE_UID;
-
- ret = idmap_backends_sid_to_unixid(dom_name, &map);
-
- if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) {
- if (map.xid.type != ID_TYPE_UID) {
- DEBUG(10, ("sid [%s] not mapped to a uid "
- "[%u,%u,%u]\n",
- sid_string_dbg(sid),
- map.status,
- map.xid.type,
- map.xid.id));
- idmap_cache_set_sid2uid(sid, -1);
- return NT_STATUS_NONE_MAPPED;
- }
- goto done;
+
+ maps[0] = &map;
+ maps[1] = NULL;
+
+ ret = idmap_sids_to_unixids(maps);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ DEBUG(10, ("error mapping sid [%s] to uid\n",
+ sid_string_dbg(sid)));
+ return ret;
}
- if (dom_name[0] != '\0') {
- /*
- * We had the task to go to a specific domain which
- * could not answer our request. Fail.
- */
- idmap_cache_set_sid2uid(sid, -1);
+ if ((map.status != ID_MAPPED) || (map.xid.type != ID_TYPE_UID)) {
+ DEBUG(10, ("sid [%s] not mapped to an uid [%u,%u,%u]\n",
+ sid_string_dbg(sid),
+ map.status,
+ map.xid.type,
+ map.xid.id));
return NT_STATUS_NONE_MAPPED;
}
- ret = idmap_new_mapping(sid, ID_TYPE_UID, &map.xid);
-
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(10, ("idmap_new_mapping failed: %s\n",
- nt_errstr(ret)));
- idmap_cache_set_sid2uid(sid, -1);
- return ret;
- }
+ *uid = map.xid.id;
-done:
- *uid = (uid_t)map.xid.id;
- idmap_cache_set_sid2uid(sid, *uid);
return NT_STATUS_OK;
}
@@ -203,68 +135,36 @@ done:
If mapping is not possible or SID maps to a UID returns an error.
*****************************************************************/
-NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid)
+NTSTATUS idmap_sid_to_gid(DOM_SID *sid, gid_t *gid)
{
NTSTATUS ret;
struct id_map map;
- bool expired;
+ struct id_map *maps[2];
DEBUG(10,("idmap_sid_to_gid: sid = [%s]\n", sid_string_dbg(sid)));
- if (idmap_cache_find_sid2gid(sid, gid, &expired)) {
- DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n",
- (int)(*gid), expired ? " (expired)": ""));
- if (expired && idmap_is_online()) {
- DEBUG(10, ("revalidating expired entry\n"));
- goto backend;
- }
- if ((*gid) == -1) {
- DEBUG(10, ("Returning negative cache entry\n"));
- return NT_STATUS_NONE_MAPPED;
- }
- DEBUG(10, ("Returning positive cache entry\n"));
- return NT_STATUS_OK;
- }
-
-backend:
map.sid = sid;
map.xid.type = ID_TYPE_GID;
-
- ret = idmap_backends_sid_to_unixid(domname, &map);
- if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) {
- if (map.xid.type != ID_TYPE_GID) {
- DEBUG(10, ("sid [%s] not mapped to a gid "
- "[%u,%u,%u]\n",
- sid_string_dbg(sid),
- map.status,
- map.xid.type,
- map.xid.id));
- idmap_cache_set_sid2gid(sid, -1);
- return NT_STATUS_NONE_MAPPED;
- }
- goto done;
+
+ maps[0] = &map;
+ maps[1] = NULL;
+
+ ret = idmap_sids_to_unixids(maps);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ DEBUG(10, ("error mapping sid [%s] to gid\n",
+ sid_string_dbg(sid)));
+ return ret;
}
- if (domname[0] != '\0') {
- /*
- * We had the task to go to a specific domain which
- * could not answer our request. Fail.
- */
- idmap_cache_set_sid2uid(sid, -1);
+ if ((map.status != ID_MAPPED) || (map.xid.type != ID_TYPE_GID)) {
+ DEBUG(10, ("sid [%s] not mapped to a gid [%u,%u]\n",
+ sid_string_dbg(sid),
+ map.status,
+ map.xid.type));
return NT_STATUS_NONE_MAPPED;
}
- ret = idmap_new_mapping(sid, ID_TYPE_GID, &map.xid);
-
- if (!NT_STATUS_IS_OK(ret)) {
- DEBUG(10, ("idmap_new_mapping failed: %s\n",
- nt_errstr(ret)));
- idmap_cache_set_sid2gid(sid, -1);
- return ret;
- }
-
-done:
*gid = map.xid.id;
- idmap_cache_set_sid2gid(sid, *gid);
+
return NT_STATUS_OK;
}
diff --git a/source/winbindd/nss_info.c b/source/winbindd/nss_info.c
index 0e8cb60257..daa3dd037d 100644
--- a/source/winbindd/nss_info.c
+++ b/source/winbindd/nss_info.c
@@ -281,47 +281,6 @@ static struct nss_domain_entry *find_nss_domain( const char *domain )
/********************************************************************
*******************************************************************/
- NTSTATUS nss_map_to_alias( TALLOC_CTX *mem_ctx, const char *domain,
- const char *name, char **alias )
-{
- struct nss_domain_entry *p;
- struct nss_info_methods *m;
-
- if ( (p = find_nss_domain( domain )) == NULL ) {
- DEBUG(4,("nss_map_to_alias: Failed to find nss domain pointer for %s\n",
- domain ));
- return NT_STATUS_NOT_FOUND;
- }
-
- m = p->backend->methods;
-
- return m->map_to_alias( mem_ctx, domain, name, alias );
-}
-
-
-/********************************************************************
- *******************************************************************/
-
- NTSTATUS nss_map_from_alias( TALLOC_CTX *mem_ctx, const char *domain,
- const char *alias, char **name )
-{
- struct nss_domain_entry *p;
- struct nss_info_methods *m;
-
- if ( (p = find_nss_domain( domain )) == NULL ) {
- DEBUG(4,("nss_map_from_alias: Failed to find nss domain pointer for %s\n",
- domain ));
- return NT_STATUS_NOT_FOUND;
- }
-
- m = p->backend->methods;
-
- return m->map_from_alias( mem_ctx, domain, alias, name );
-}
-
-/********************************************************************
- *******************************************************************/
-
NTSTATUS nss_close( const char *parameters )
{
struct nss_domain_entry *p = nss_domain_list;
diff --git a/source/winbindd/nss_info_template.c b/source/winbindd/nss_info_template.c
index d8f903ddd0..aaf02e4abe 100644
--- a/source/winbindd/nss_info_template.c
+++ b/source/winbindd/nss_info_template.c
@@ -45,8 +45,6 @@ static NTSTATUS nss_template_get_info( struct nss_domain_entry *e,
if ( !homedir || !shell || !gecos )
return NT_STATUS_INVALID_PARAMETER;
- /* protect against home directories using whitespace in the
- username */
*homedir = talloc_strdup( ctx, lp_template_homedir() );
*shell = talloc_strdup( ctx, lp_template_shell() );
*gecos = NULL;
@@ -58,28 +56,6 @@ static NTSTATUS nss_template_get_info( struct nss_domain_entry *e,
return NT_STATUS_OK;
}
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS nss_template_map_to_alias( TALLOC_CTX *mem_ctx,
- const char *domain,
- const char *name,
- char **alias )
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS nss_template_map_from_alias( TALLOC_CTX *mem_ctx,
- const char *domain,
- const char *alias,
- char **name )
-{
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
/************************************************************************
***********************************************************************/
@@ -93,11 +69,9 @@ static NTSTATUS nss_template_close( void )
***********************************************************************/
static struct nss_info_methods nss_template_methods = {
- .init = nss_template_init,
- .get_nss_info = nss_template_get_info,
- .map_to_alias = nss_template_map_to_alias,
- .map_from_alias = nss_template_map_from_alias,
- .close_fn = nss_template_close
+ .init = nss_template_init,
+ .get_nss_info = nss_template_get_info,
+ .close_fn = nss_template_close
};
NTSTATUS nss_info_template_init( void )
diff --git a/source/winbindd/winbindd.c b/source/winbindd/winbindd.c
index 44b5415726..876b2e8390 100644
--- a/source/winbindd/winbindd.c
+++ b/source/winbindd/winbindd.c
@@ -47,12 +47,9 @@ struct messaging_context *winbind_messaging_context(void)
{
static struct messaging_context *ctx;
- if (ctx == NULL) {
- ctx = messaging_init(NULL, server_id_self(),
- winbind_event_context());
- }
- if (ctx == NULL) {
- DEBUG(0, ("Could not init winbind messaging context.\n"));
+ if (!ctx && !(ctx = messaging_init(NULL, server_id_self(),
+ winbind_event_context()))) {
+ smb_panic("Could not init winbind messaging context");
}
return ctx;
}
@@ -340,6 +337,9 @@ static struct winbindd_dispatch_table {
{ WINBINDD_SID_TO_GID, winbindd_sid_to_gid, "SID_TO_GID" },
{ WINBINDD_UID_TO_SID, winbindd_uid_to_sid, "UID_TO_SID" },
{ WINBINDD_GID_TO_SID, winbindd_gid_to_sid, "GID_TO_SID" },
+#if 0 /* DISABLED until we fix the interface in Samba 3.0.26 --jerry */
+ { WINBINDD_SIDS_TO_XIDS, winbindd_sids_to_unixids, "SIDS_TO_XIDS" },
+#endif /* end DISABLED */
{ WINBINDD_ALLOCATE_UID, winbindd_allocate_uid, "ALLOCATE_UID" },
{ WINBINDD_ALLOCATE_GID, winbindd_allocate_gid, "ALLOCATE_GID" },
{ WINBINDD_SET_MAPPING, winbindd_set_mapping, "SET_MAPPING" },
@@ -534,6 +534,7 @@ static void request_len_recv(void *private_data, bool success);
static void request_recv(void *private_data, bool success);
static void request_main_recv(void *private_data, bool success);
static void request_finished(struct winbindd_cli_state *state);
+void request_finished_cont(void *private_data, bool success);
static void response_main_sent(void *private_data, bool success);
static void response_extra_sent(void *private_data, bool success);
@@ -542,7 +543,10 @@ static void response_extra_sent(void *private_data, bool success)
struct winbindd_cli_state *state =
talloc_get_type_abort(private_data, struct winbindd_cli_state);
- TALLOC_FREE(state->mem_ctx);
+ if (state->mem_ctx != NULL) {
+ talloc_destroy(state->mem_ctx);
+ state->mem_ctx = NULL;
+ }
if (!success) {
state->finished = True;
@@ -566,7 +570,10 @@ static void response_main_sent(void *private_data, bool success)
}
if (state->response.length == sizeof(state->response)) {
- TALLOC_FREE(state->mem_ctx);
+ if (state->mem_ctx != NULL) {
+ talloc_destroy(state->mem_ctx);
+ state->mem_ctx = NULL;
+ }
setup_async_read(&state->fd_event, &state->request,
sizeof(uint32), request_len_recv, state);
@@ -600,6 +607,17 @@ void request_ok(struct winbindd_cli_state *state)
request_finished(state);
}
+void request_finished_cont(void *private_data, bool success)
+{
+ struct winbindd_cli_state *state =
+ talloc_get_type_abort(private_data, struct winbindd_cli_state);
+
+ if (success)
+ request_ok(state);
+ else
+ request_error(state);
+}
+
static void request_len_recv(void *private_data, bool success)
{
struct winbindd_cli_state *state =
@@ -747,7 +765,10 @@ static void remove_client(struct winbindd_cli_state *state)
SAFE_FREE(state->response.extra_data.data);
- TALLOC_FREE(state->mem_ctx);
+ if (state->mem_ctx != NULL) {
+ talloc_destroy(state->mem_ctx);
+ state->mem_ctx = NULL;
+ }
remove_fd_event(&state->fd_event);
@@ -1025,6 +1046,8 @@ int main(int argc, char **argv, char **envp)
load_case_tables();
+ db_tdb2_setup_messaging(NULL, false);
+
/* Initialise for running in non-root mode */
sec_init();
@@ -1112,9 +1135,12 @@ int main(int argc, char **argv, char **envp)
/* Initialise messaging system */
if (winbind_messaging_context() == NULL) {
+ DEBUG(0, ("unable to initialize messaging system\n"));
exit(1);
}
+ db_tdb2_setup_messaging(winbind_messaging_context(), true);
+
if (!reload_services_file(NULL)) {
DEBUG(0, ("error opening config file\n"));
exit(1);
@@ -1141,6 +1167,12 @@ int main(int argc, char **argv, char **envp)
namecache_enable();
+ /* Winbind daemon initialisation */
+
+ if ( ! NT_STATUS_IS_OK(idmap_init_cache()) ) {
+ DEBUG(1, ("Could not init idmap cache!\n"));
+ }
+
/* Unblock all signals we are interested in as they may have been
blocked by the parent process. */
diff --git a/source/winbindd/winbindd.h b/source/winbindd/winbindd.h
index 1b8cd9163f..42a1100f02 100644
--- a/source/winbindd/winbindd.h
+++ b/source/winbindd/winbindd.h
@@ -24,7 +24,6 @@
#define _WINBINDD_H
#include "nsswitch/winbind_struct_protocol.h"
-#include "nsswitch/libwbclient/wbclient.h"
#ifdef HAVE_LIBNSCD
#include <libnscd.h>
@@ -196,15 +195,7 @@ struct winbindd_domain {
void *private_data;
- /*
- * idmap config settings, used to tell the idmap child which
- * special domain config to use for a mapping
- */
- bool have_idmap_config;
- uint32_t id_range_low, id_range_high;
-
/* A working DC */
- pid_t dc_probe_pid; /* Child we're using to detect the DC. */
fstring dcname;
struct sockaddr_storage dcaddr;
@@ -387,6 +378,4 @@ enum ent_type {
#define IS_DOMAIN_OFFLINE(x) ( lp_winbind_offline_logon() && \
( get_global_winbindd_state_offline() \
|| !(x)->online ) )
-#define IS_DOMAIN_ONLINE(x) (!IS_DOMAIN_OFFLINE(x))
-
#endif /* _WINBINDD_H */
diff --git a/source/winbindd/winbindd_ads.c b/source/winbindd/winbindd_ads.c
index 894e7866b3..c588726e30 100644
--- a/source/winbindd/winbindd_ads.c
+++ b/source/winbindd/winbindd_ads.c
@@ -1195,7 +1195,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
}
result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
- cli->desthost,
+ cli->cli->desthost,
flags,
&trusts,
NULL);
diff --git a/source/winbindd/winbindd_async.c b/source/winbindd/winbindd_async.c
index 1481aed8e1..f29953d9bb 100644
--- a/source/winbindd/winbindd_async.c
+++ b/source/winbindd/winbindd_async.c
@@ -468,7 +468,7 @@ static void listent_recv(TALLOC_CTX *mem_ctx, bool success,
}
cont(private_data, True, response->data.name.dom_name,
- (char *)response->extra_data.data);
+ response->extra_data.data);
SAFE_FREE(response->extra_data.data);
}
diff --git a/source/winbindd/winbindd_cache.c b/source/winbindd/winbindd_cache.c
index 360e915bc4..d3e47d0874 100644
--- a/source/winbindd/winbindd_cache.c
+++ b/source/winbindd/winbindd_cache.c
@@ -502,8 +502,14 @@ static void refresh_sequence_number(struct winbindd_domain *domain, bool force)
mode domain or not. And that we can contact it. */
if ( winbindd_can_contact_domain( domain ) ) {
+ struct winbindd_methods *orig_backend = domain->backend;
status = domain->backend->sequence_number(domain,
&domain->sequence_number);
+ if (domain->backend != orig_backend) {
+ /* Try again. */
+ status = domain->backend->sequence_number(domain,
+ &domain->sequence_number);
+ }
} else {
/* just use the current time */
status = NT_STATUS_OK;
@@ -934,8 +940,6 @@ static void wcache_save_lockout_policy(struct winbindd_domain *domain,
centry_free(centry);
}
-
-
static void wcache_save_password_policy(struct winbindd_domain *domain,
NTSTATUS status,
struct samr_DomInfo1 *policy)
@@ -959,209 +963,6 @@ static void wcache_save_password_policy(struct winbindd_domain *domain,
centry_free(centry);
}
-/***************************************************************************
- ***************************************************************************/
-
-static void wcache_save_username_alias(struct winbindd_domain *domain,
- NTSTATUS status,
- const char *name, const char *alias)
-{
- struct cache_entry *centry;
- fstring uname;
-
- if ( (centry = centry_start(domain, status)) == NULL )
- return;
-
- centry_put_string( centry, alias );
-
- fstrcpy(uname, name);
- strupper_m(uname);
- centry_end(centry, "NSS/NA/%s", uname);
-
- DEBUG(10,("wcache_save_username_alias: %s -> %s\n", name, alias ));
-
- centry_free(centry);
-}
-
-static void wcache_save_alias_username(struct winbindd_domain *domain,
- NTSTATUS status,
- const char *alias, const char *name)
-{
- struct cache_entry *centry;
- fstring uname;
-
- if ( (centry = centry_start(domain, status)) == NULL )
- return;
-
- centry_put_string( centry, name );
-
- fstrcpy(uname, alias);
- strupper_m(uname);
- centry_end(centry, "NSS/AN/%s", uname);
-
- DEBUG(10,("wcache_save_alias_username: %s -> %s\n", alias, name ));
-
- centry_free(centry);
-}
-
-/***************************************************************************
- ***************************************************************************/
-
-NTSTATUS resolve_username_to_alias( TALLOC_CTX *mem_ctx,
- struct winbindd_domain *domain,
- const char *name, char **alias )
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- char *upper_name;
-
- if ( domain->internal )
- return NT_STATUS_NOT_SUPPORTED;
-
- if (!cache->tdb)
- goto do_query;
-
- if ( (upper_name = SMB_STRDUP(name)) == NULL )
- return NT_STATUS_NO_MEMORY;
- strupper_m(upper_name);
-
- centry = wcache_fetch(cache, domain, "NSS/NA/%s", upper_name);
-
- SAFE_FREE( upper_name );
-
- if (!centry)
- goto do_query;
-
- status = centry->status;
-
- if (!NT_STATUS_IS_OK(status)) {
- centry_free(centry);
- return status;
- }
-
- *alias = centry_string( centry, mem_ctx );
-
- centry_free(centry);
-
- DEBUG(10,("resolve_username_to_alias: [Cached] - mapped %s to %s\n",
- name, *alias ? *alias : "(none)"));
-
- return (*alias) ? NT_STATUS_OK : NT_STATUS_OBJECT_NAME_NOT_FOUND;
-
-do_query:
-
- /* If its not in cache and we are offline, then fail */
-
- if ( get_global_winbindd_state_offline() || !domain->online ) {
- DEBUG(8,("resolve_username_to_alias: rejecting query "
- "in offline mode\n"));
- return NT_STATUS_NOT_FOUND;
- }
-
- status = nss_map_to_alias( mem_ctx, domain->name, name, alias );
-
- if ( NT_STATUS_IS_OK( status ) ) {
- wcache_save_username_alias(domain, status, name, *alias);
- }
-
- if ( NT_STATUS_EQUAL( status, NT_STATUS_NONE_MAPPED ) ) {
- wcache_save_username_alias(domain, status, name, "(NULL)");
- }
-
- DEBUG(5,("resolve_username_to_alias: backend query returned %s\n",
- nt_errstr(status)));
-
- if ( NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) ) {
- set_domain_offline( domain );
- }
-
- return status;
-}
-
-/***************************************************************************
- ***************************************************************************/
-
-NTSTATUS resolve_alias_to_username( TALLOC_CTX *mem_ctx,
- struct winbindd_domain *domain,
- const char *alias, char **name )
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- char *upper_name;
-
- if ( domain->internal )
- return NT_STATUS_NOT_SUPPORTED;
-
- if (!cache->tdb)
- goto do_query;
-
- if ( (upper_name = SMB_STRDUP(alias)) == NULL )
- return NT_STATUS_NO_MEMORY;
- strupper_m(upper_name);
-
- centry = wcache_fetch(cache, domain, "NSS/AN/%s", upper_name);
-
- SAFE_FREE( upper_name );
-
- if (!centry)
- goto do_query;
-
- status = centry->status;
-
- if (!NT_STATUS_IS_OK(status)) {
- centry_free(centry);
- return status;
- }
-
- *name = centry_string( centry, mem_ctx );
-
- centry_free(centry);
-
- DEBUG(10,("resolve_alias_to_username: [Cached] - mapped %s to %s\n",
- alias, *name ? *name : "(none)"));
-
- return (*name) ? NT_STATUS_OK : NT_STATUS_OBJECT_NAME_NOT_FOUND;
-
-do_query:
-
- /* If its not in cache and we are offline, then fail */
-
- if ( get_global_winbindd_state_offline() || !domain->online ) {
- DEBUG(8,("resolve_alias_to_username: rejecting query "
- "in offline mode\n"));
- return NT_STATUS_NOT_FOUND;
- }
-
- /* an alias cannot contain a domain prefix or '@' */
-
- if (strchr(alias, '\\') || strchr(alias, '@')) {
- DEBUG(10,("resolve_alias_to_username: skipping fully "
- "qualified name %s\n", alias));
- return NT_STATUS_OBJECT_NAME_INVALID;
- }
-
- status = nss_map_from_alias( mem_ctx, domain->name, alias, name );
-
- if ( NT_STATUS_IS_OK( status ) ) {
- wcache_save_alias_username( domain, status, alias, *name );
- }
-
- if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
- wcache_save_alias_username(domain, status, alias, "(NULL)");
- }
-
- DEBUG(5,("resolve_alias_to_username: backend query returned %s\n",
- nt_errstr(status)));
-
- if ( NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) ) {
- set_domain_offline( domain );
- }
-
- return status;
-}
-
NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const DOM_SID *sid)
{
struct winbind_cache *cache = get_cache(domain);
@@ -3462,48 +3263,6 @@ static int validate_pwinfo(TALLOC_CTX *mem_ctx, const char *keystr,
return 0;
}
-static int validate_nss_an(TALLOC_CTX *mem_ctx, const char *keystr,
- TDB_DATA dbuf,
- struct tdb_validation_status *state)
-{
- struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
-
- if (!centry) {
- return 1;
- }
-
- (void)centry_string( centry, mem_ctx );
-
- centry_free(centry);
-
- if (!(state->success)) {
- return 1;
- }
- DEBUG(10,("validate_pwinfo: %s ok\n", keystr));
- return 0;
-}
-
-static int validate_nss_na(TALLOC_CTX *mem_ctx, const char *keystr,
- TDB_DATA dbuf,
- struct tdb_validation_status *state)
-{
- struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
-
- if (!centry) {
- return 1;
- }
-
- (void)centry_string( centry, mem_ctx );
-
- centry_free(centry);
-
- if (!(state->success)) {
- return 1;
- }
- DEBUG(10,("validate_pwinfo: %s ok\n", keystr));
- return 0;
-}
-
static int validate_trustdoms(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf,
struct tdb_validation_status *state)
{
@@ -3605,8 +3364,6 @@ struct key_val_struct {
{"NSS/PWINFO/", validate_pwinfo},
{"TRUSTDOMS/", validate_trustdoms},
{"TRUSTDOMCACHE/", validate_trustdomcache},
- {"NSS/NA/", validate_nss_na},
- {"NSS/AN/", validate_nss_an},
{"WINBINDD_OFFLINE", validate_offline},
{WINBINDD_CACHE_VERSION_KEYSTR, validate_cache_version},
{NULL, NULL}
diff --git a/source/winbindd/winbindd_cm.c b/source/winbindd/winbindd_cm.c
index b9ba486f8a..511d839ae9 100644
--- a/source/winbindd/winbindd_cm.c
+++ b/source/winbindd/winbindd_cm.c
@@ -171,33 +171,20 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain)
struct dc_name_ip *dcs = NULL;
int num_dcs = 0;
TALLOC_CTX *mem_ctx = NULL;
+ pid_t child_pid;
pid_t parent_pid = sys_getpid();
/* Stop zombies */
CatchChild();
- if (domain->dc_probe_pid != (pid_t)-1) {
- /*
- * We might already have a DC probe
- * child working, check.
- */
- if (process_exists_by_pid(domain->dc_probe_pid)) {
- DEBUG(10,("fork_child_dc_connect: pid %u already "
- "checking for DC's.\n",
- (unsigned int)domain->dc_probe_pid));
- return true;
- }
- domain->dc_probe_pid = (pid_t)-1;
- }
-
- domain->dc_probe_pid = sys_fork();
+ child_pid = sys_fork();
- if (domain->dc_probe_pid == (pid_t)-1) {
+ if (child_pid == -1) {
DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
return False;
}
- if (domain->dc_probe_pid != (pid_t)0) {
+ if (child_pid != 0) {
/* Parent */
messaging_register(winbind_messaging_context(), NULL,
MSG_WINBIND_TRY_TO_GO_ONLINE,
@@ -214,11 +201,6 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain)
if (!reinit_after_fork(winbind_messaging_context(), true)) {
DEBUG(0,("reinit_after_fork() failed\n"));
- messaging_send_buf(winbind_messaging_context(),
- pid_to_procid(parent_pid),
- MSG_WINBIND_FAILED_TO_GO_ONLINE,
- (uint8 *)domain->name,
- strlen(domain->name)+1);
_exit(0);
}
@@ -236,11 +218,6 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain)
mem_ctx = talloc_init("fork_child_dc_connect");
if (!mem_ctx) {
DEBUG(0,("talloc_init failed.\n"));
- messaging_send_buf(winbind_messaging_context(),
- pid_to_procid(parent_pid),
- MSG_WINBIND_FAILED_TO_GO_ONLINE,
- (uint8 *)domain->name,
- strlen(domain->name)+1);
_exit(0);
}
@@ -314,12 +291,12 @@ static void check_domain_online_handler(struct event_context *ctx,
static void calc_new_online_timeout_check(struct winbindd_domain *domain)
{
- int wbr = lp_winbind_reconnect_delay();
+ int wbc = lp_winbind_cache_time();
if (domain->startup) {
domain->check_online_timeout = 10;
- } else if (domain->check_online_timeout < wbr) {
- domain->check_online_timeout = wbr;
+ } else if (domain->check_online_timeout < wbc) {
+ domain->check_online_timeout = wbc;
}
}
@@ -359,7 +336,7 @@ void set_domain_offline(struct winbindd_domain *domain)
}
/* If we're in statup mode, check again in 10 seconds, not in
- lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
+ lp_winbind_cache_time() seconds (which is 5 mins by default). */
calc_new_online_timeout_check(domain);
@@ -621,7 +598,7 @@ static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
/* This call can take a long time - allow the server to time out.
35 seconds should do it. */
- orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
+ orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);
if (our_domain->active_directory) {
struct netr_DsRGetDCNameInfo *domain_info = NULL;
@@ -661,7 +638,7 @@ static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
}
/* And restore our original timeout. */
- rpccli_set_timeout(netlogon_pipe, orig_timeout);
+ cli_set_timeout(netlogon_pipe->cli, orig_timeout);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n",
@@ -733,14 +710,8 @@ static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
if (machine_krb5_principal != NULL)
{
- struct winbindd_domain *our_domain = find_our_domain();
-
- if (!our_domain) {
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
-
if (asprintf(machine_krb5_principal, "%s$@%s",
- account_name, our_domain->alt_name) == -1)
+ account_name, lp_realm()) == -1)
{
return NT_STATUS_NO_MEMORY;
}
@@ -837,7 +808,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
goto done;
}
- if (!is_dc_trusted_domain_situation(domain->name) &&
+ if (!is_trusted_domain_situation(domain->name) &&
(*cli)->protocol >= PROTOCOL_NT1 &&
(*cli)->capabilities & CAP_EXTENDED_SECURITY)
{
@@ -1091,16 +1062,14 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx,
if (lp_security() == SEC_ADS) {
ADS_STRUCT *ads;
- ADS_STATUS ads_status;
char addr[INET6_ADDRSTRLEN];
print_sockaddr(addr, sizeof(addr), pss);
- ads = ads_init(domain->alt_name, domain->name, addr);
+ ads = ads_init(domain->alt_name, domain->name, NULL);
ads->auth.flags |= ADS_AUTH_NO_BIND;
- ads_status = ads_connect(ads);
- if (ADS_ERR_OK(ads_status)) {
+ if (ads_try_connect(ads, addr)) {
/* We got a cldap packet. */
fstrcpy(name, ads->config.ldap_server_name);
namecache_store(name, 0x20, 1, &ip_list);
@@ -1535,27 +1504,33 @@ void invalidate_cm_connection(struct winbindd_cm_conn *conn)
}
if (conn->samr_pipe != NULL) {
- TALLOC_FREE(conn->samr_pipe);
- /* Ok, it must be dead. Drop timeout to 0.5 sec. */
- if (conn->cli) {
- cli_set_timeout(conn->cli, 500);
+ if (!cli_rpc_pipe_close(conn->samr_pipe)) {
+ /* Ok, it must be dead. Drop timeout to 0.5 sec. */
+ if (conn->cli) {
+ cli_set_timeout(conn->cli, 500);
+ }
}
+ conn->samr_pipe = NULL;
}
if (conn->lsa_pipe != NULL) {
- TALLOC_FREE(conn->lsa_pipe);
- /* Ok, it must be dead. Drop timeout to 0.5 sec. */
- if (conn->cli) {
- cli_set_timeout(conn->cli, 500);
+ if (!cli_rpc_pipe_close(conn->lsa_pipe)) {
+ /* Ok, it must be dead. Drop timeout to 0.5 sec. */
+ if (conn->cli) {
+ cli_set_timeout(conn->cli, 500);
+ }
}
+ conn->lsa_pipe = NULL;
}
if (conn->netlogon_pipe != NULL) {
- TALLOC_FREE(conn->netlogon_pipe);
- /* Ok, it must be dead. Drop timeout to 0.5 sec. */
- if (conn->cli) {
- cli_set_timeout(conn->cli, 500);
+ if (!cli_rpc_pipe_close(conn->netlogon_pipe)) {
+ /* Ok, it must be dead. Drop timeout to 0.5 sec. */
+ if (conn->cli) {
+ cli_set_timeout(conn->cli, 500);
+ }
}
+ conn->netlogon_pipe = NULL;
}
if (conn->cli) {
@@ -1706,7 +1681,7 @@ static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
}
result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
- cli->desthost,
+ cli->cli->desthost,
flags,
&trusts,
NULL);
@@ -1789,11 +1764,10 @@ static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
- result = cli_rpc_pipe_open_noauth(domain->conn.cli,
- &ndr_table_dssetup.syntax_id,
- &cli);
+ cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_DSSETUP,
+ &result);
- if (!NT_STATUS_IS_OK(result)) {
+ if (cli == NULL) {
DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
"PI_DSSETUP on domain %s: (%s)\n",
domain->name, nt_errstr(result)));
@@ -1809,7 +1783,7 @@ static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
DS_ROLE_BASIC_INFORMATION,
&info,
&werr);
- TALLOC_FREE(cli);
+ cli_rpc_pipe_close(cli);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
@@ -1837,14 +1811,13 @@ static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
}
no_dssetup:
- result = cli_rpc_pipe_open_noauth(domain->conn.cli,
- &ndr_table_lsarpc.syntax_id, &cli);
+ cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
- if (!NT_STATUS_IS_OK(result)) {
+ if (cli == NULL) {
DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
"PI_LSARPC on domain %s: (%s)\n",
domain->name, nt_errstr(result)));
- TALLOC_FREE(cli);
+ cli_rpc_pipe_close(cli);
TALLOC_FREE(mem_ctx);
return;
}
@@ -1924,7 +1897,7 @@ done:
DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
domain->name, domain->active_directory ? "" : "NOT "));
- TALLOC_FREE(cli);
+ cli_rpc_pipe_close(cli);
TALLOC_FREE(mem_ctx);
@@ -2044,15 +2017,14 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
/* We have an authenticated connection. Use a NTLMSSP SPNEGO
authenticated SAMR pipe with sign & seal. */
- result = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
- &ndr_table_samr.syntax_id,
- PIPE_AUTH_LEVEL_PRIVACY,
- domain_name,
- machine_account,
- machine_password,
- &conn->samr_pipe);
-
- if (!NT_STATUS_IS_OK(result)) {
+ conn->samr_pipe =
+ cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, PI_SAMR,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain_name,
+ machine_account,
+ machine_password, &result);
+
+ if (conn->samr_pipe == NULL) {
DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
"pipe for domain %s using NTLMSSP "
"authenticated pipe: user %s\\%s. Error was "
@@ -2067,7 +2039,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
domain_name, machine_account));
result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
- conn->samr_pipe->desthost,
+ conn->samr_pipe->cli->desthost,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&conn->sam_connect_handle);
if (NT_STATUS_IS_OK(result)) {
@@ -2076,7 +2048,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_Connect2 "
"failed for domain %s, error was %s. Trying schannel\n",
domain->name, nt_errstr(result) ));
- TALLOC_FREE(conn->samr_pipe);
+ cli_rpc_pipe_close(conn->samr_pipe);
schannel:
@@ -2088,11 +2060,11 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
"for domain %s, trying anon\n", domain->name));
goto anonymous;
}
- result = cli_rpc_pipe_open_schannel_with_key
- (conn->cli, &ndr_table_samr.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
- domain->name, p_dcinfo, &conn->samr_pipe);
+ conn->samr_pipe = cli_rpc_pipe_open_schannel_with_key
+ (conn->cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY,
+ domain->name, p_dcinfo, &result);
- if (!NT_STATUS_IS_OK(result)) {
+ if (conn->samr_pipe == NULL) {
DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
"domain %s using schannel. Error was %s\n",
domain->name, nt_errstr(result) ));
@@ -2102,7 +2074,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
"schannel.\n", domain->name ));
result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
- conn->samr_pipe->desthost,
+ conn->samr_pipe->cli->desthost,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&conn->sam_connect_handle);
if (NT_STATUS_IS_OK(result)) {
@@ -2111,20 +2083,21 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_Connect2 failed "
"for domain %s, error was %s. Trying anonymous\n",
domain->name, nt_errstr(result) ));
- TALLOC_FREE(conn->samr_pipe);
+ cli_rpc_pipe_close(conn->samr_pipe);
anonymous:
/* Finally fall back to anonymous. */
- result = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
- &conn->samr_pipe);
+ conn->samr_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR,
+ &result);
- if (!NT_STATUS_IS_OK(result)) {
+ if (conn->samr_pipe == NULL) {
+ result = NT_STATUS_PIPE_NOT_AVAILABLE;
goto done;
}
result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
- conn->samr_pipe->desthost,
+ conn->samr_pipe->cli->desthost,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&conn->sam_connect_handle);
if (!NT_STATUS_IS_OK(result)) {
@@ -2185,13 +2158,11 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
/* We have an authenticated connection. Use a NTLMSSP SPNEGO
* authenticated LSA pipe with sign & seal. */
- result = cli_rpc_pipe_open_spnego_ntlmssp
- (conn->cli, &ndr_table_lsarpc.syntax_id,
- PIPE_AUTH_LEVEL_PRIVACY,
- conn->cli->domain, conn->cli->user_name, conn_pwd,
- &conn->lsa_pipe);
+ conn->lsa_pipe = cli_rpc_pipe_open_spnego_ntlmssp
+ (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
+ conn->cli->domain, conn->cli->user_name, conn_pwd, &result);
- if (!NT_STATUS_IS_OK(result)) {
+ if (conn->lsa_pipe == NULL) {
DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
"domain %s using NTLMSSP authenticated pipe: user "
"%s\\%s. Error was %s. Trying schannel.\n",
@@ -2214,7 +2185,7 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
"schannel\n"));
- TALLOC_FREE(conn->lsa_pipe);
+ cli_rpc_pipe_close(conn->lsa_pipe);
schannel:
@@ -2226,12 +2197,11 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
"for domain %s, trying anon\n", domain->name));
goto anonymous;
}
- result = cli_rpc_pipe_open_schannel_with_key
- (conn->cli, &ndr_table_lsarpc.syntax_id,
- PIPE_AUTH_LEVEL_PRIVACY,
- domain->name, p_dcinfo, &conn->lsa_pipe);
+ conn->lsa_pipe = cli_rpc_pipe_open_schannel_with_key
+ (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
+ domain->name, p_dcinfo, &result);
- if (!NT_STATUS_IS_OK(result)) {
+ if (conn->lsa_pipe == NULL) {
DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
"domain %s using schannel. Error was %s\n",
domain->name, nt_errstr(result) ));
@@ -2250,14 +2220,13 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
"anonymous\n"));
- TALLOC_FREE(conn->lsa_pipe);
+ cli_rpc_pipe_close(conn->lsa_pipe);
anonymous:
- result = cli_rpc_pipe_open_noauth(conn->cli,
- &ndr_table_lsarpc.syntax_id,
- &conn->lsa_pipe);
- if (!NT_STATUS_IS_OK(result)) {
+ conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_LSARPC,
+ &result);
+ if (conn->lsa_pipe == NULL) {
result = NT_STATUS_PIPE_NOT_AVAILABLE;
goto done;
}
@@ -2307,10 +2276,9 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
return NT_STATUS_OK;
}
- result = cli_rpc_pipe_open_noauth(conn->cli,
- &ndr_table_netlogon.syntax_id,
- &netlogon_pipe);
- if (!NT_STATUS_IS_OK(result)) {
+ netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON,
+ &result);
+ if (netlogon_pipe == NULL) {
return result;
}
@@ -2327,7 +2295,7 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
&sec_chan_type))
{
- TALLOC_FREE(netlogon_pipe);
+ cli_rpc_pipe_close(netlogon_pipe);
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
@@ -2342,14 +2310,14 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
&neg_flags);
if (!NT_STATUS_IS_OK(result)) {
- TALLOC_FREE(netlogon_pipe);
+ cli_rpc_pipe_close(netlogon_pipe);
return result;
}
if ((lp_client_schannel() == True) &&
((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
DEBUG(3, ("Server did not offer schannel\n"));
- TALLOC_FREE(netlogon_pipe);
+ cli_rpc_pipe_close(netlogon_pipe);
return NT_STATUS_ACCESS_DENIED;
}
@@ -2373,15 +2341,18 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
part of the new pipe auth struct.
*/
- result = cli_rpc_pipe_open_schannel_with_key(
- conn->cli, &ndr_table_netlogon.syntax_id,
- PIPE_AUTH_LEVEL_PRIVACY, domain->name, netlogon_pipe->dc,
- &conn->netlogon_pipe);
+ conn->netlogon_pipe =
+ cli_rpc_pipe_open_schannel_with_key(conn->cli,
+ PI_NETLOGON,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain->name,
+ netlogon_pipe->dc,
+ &result);
/* We can now close the initial netlogon pipe. */
- TALLOC_FREE(netlogon_pipe);
+ cli_rpc_pipe_close(netlogon_pipe);
- if (!NT_STATUS_IS_OK(result)) {
+ if (conn->netlogon_pipe == NULL) {
DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
"was %s\n", nt_errstr(result)));
diff --git a/source/winbindd/winbindd_dual.c b/source/winbindd/winbindd_dual.c
index 9e9a244acf..f2be6d692c 100644
--- a/source/winbindd/winbindd_dual.c
+++ b/source/winbindd/winbindd_dual.c
@@ -196,12 +196,10 @@ static void async_request_fail(struct winbindd_async_request *state)
TALLOC_FREE(state->reply_timeout_event);
- /* If child exists and is not already reaped,
- send kill signal to child. */
+ SMB_ASSERT(state->child_pid != (pid_t)0);
- if ((state->child->pid != (pid_t)0) &&
- (state->child->pid != (pid_t)-1) &&
- (state->child->pid == state->child_pid)) {
+ /* If not already reaped, send kill signal to child. */
+ if (state->child->pid == state->child_pid) {
kill(state->child_pid, SIGTERM);
/*
@@ -297,14 +295,12 @@ static void schedule_async_request(struct winbindd_child *child)
}
if ((child->pid == 0) && (!fork_domain_child(child))) {
- /* fork_domain_child failed.
- Cancel all outstanding requests */
+ /* Cancel all outstanding requests */
while (request != NULL) {
/* request might be free'd in the continuation */
struct winbindd_async_request *next = request->next;
-
- async_request_fail(request);
+ request->continuation(request->private_data, False);
request = next;
}
return;
@@ -1037,8 +1033,6 @@ static bool fork_domain_child(struct winbindd_child *child)
/* Child */
- DEBUG(10, ("Child process %d\n", (int)sys_getpid()));
-
/* Stop zombies in children */
CatchChild();
@@ -1111,10 +1105,6 @@ static bool fork_domain_child(struct winbindd_child *child)
}
}
- if (primary_domain == NULL) {
- smb_panic("no primary domain found");
- }
-
/* Ensure we're not handling an event inherited from
our parent. */
diff --git a/source/winbindd/winbindd_group.c b/source/winbindd/winbindd_group.c
index 088f946877..f81caa22b6 100644
--- a/source/winbindd/winbindd_group.c
+++ b/source/winbindd/winbindd_group.c
@@ -45,9 +45,7 @@ static void add_member(const char *domain, const char *user,
Add member users resulting from sid. Expand if it is a domain group.
**********************************************************************/
-static void add_expanded_sid(const DOM_SID *sid,
- char **pp_members,
- size_t *p_num_members)
+static void add_expanded_sid(const DOM_SID *sid, char **pp_members, size_t *p_num_members)
{
DOM_SID dom_sid;
uint32 rid;
@@ -145,8 +143,8 @@ static void add_expanded_sid(const DOM_SID *sid,
}
static bool fill_passdb_alias_grmem(struct winbindd_domain *domain,
- DOM_SID *group_sid, size_t *num_gr_mem,
- char **gr_mem, size_t *gr_mem_len)
+ DOM_SID *group_sid,
+ size_t *num_gr_mem, char **gr_mem, size_t *gr_mem_len)
{
DOM_SID *members;
size_t i, num_members;
@@ -179,37 +177,17 @@ static bool fill_passdb_alias_grmem(struct winbindd_domain *domain,
/* Fill a grent structure from various other information */
-static bool fill_grent(TALLOC_CTX *mem_ctx, struct winbindd_gr *gr,
- const char *dom_name,
- char *gr_name, gid_t unix_gid)
+static bool fill_grent(struct winbindd_gr *gr, const char *dom_name,
+ const char *gr_name, gid_t unix_gid)
{
fstring full_group_name;
- char *mapped_name = NULL;
- struct winbindd_domain *domain = find_domain_from_name_noinit(dom_name);
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- nt_status = normalize_name_map(mem_ctx, domain, gr_name,
- &mapped_name);
-
- /* Basic whitespace replacement */
- if (NT_STATUS_IS_OK(nt_status)) {
- fill_domain_username(full_group_name, dom_name,
- mapped_name, true);
- }
- /* Mapped to an aliase */
- else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) {
- fstrcpy(full_group_name, mapped_name);
- }
- /* no change */
- else {
- fill_domain_username( full_group_name, dom_name,
- gr_name, True );
- }
+ fill_domain_username( full_group_name, dom_name, gr_name, True );
gr->gr_gid = unix_gid;
-
+
/* Group name and password */
-
+
safe_strcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name) - 1);
safe_strcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1);
@@ -230,7 +208,7 @@ static bool fill_grent_mem_domusers( TALLOC_CTX *mem_ctx,
struct winbindd_cli_state *state,
DOM_SID *group_sid,
enum lsa_SidType group_name_type,
- size_t *num_gr_mem, char **gr_mem,
+ size_t *num_gr_mem, char **gr_mem,
size_t *gr_mem_len)
{
DOM_SID querying_user_sid;
@@ -251,12 +229,10 @@ static bool fill_grent_mem_domusers( TALLOC_CTX *mem_ctx,
if (sys_getpeereid(state->sock, &ret_uid)==0) {
/* We know who's asking - look up their SID if
it's one we've mapped before. */
- status = idmap_uid_to_sid(domain->name,
- &querying_user_sid, ret_uid);
+ status = idmap_uid_to_sid(&querying_user_sid, ret_uid);
if (NT_STATUS_IS_OK(status)) {
pquerying_user_sid = &querying_user_sid;
- DEBUG(10,("fill_grent_mem_domain_users: "
- "querying uid %u -> %s\n",
+ DEBUG(10,("fill_grent_mem_domain_users: querying uid %u -> %s\n",
(unsigned int)ret_uid,
sid_string_dbg(pquerying_user_sid)));
}
@@ -266,23 +242,22 @@ static bool fill_grent_mem_domusers( TALLOC_CTX *mem_ctx,
/* Only look up if it was a winbindd user in this domain. */
if (pquerying_user_sid &&
(sid_compare_domain(pquerying_user_sid, &domain->sid) == 0)) {
-
+
DEBUG(10,("fill_grent_mem_domain_users: querying user = %s\n",
sid_string_dbg(pquerying_user_sid) ));
-
+
status = domain->methods->lookup_usergroups(domain,
mem_ctx,
pquerying_user_sid,
&num_groups,
&user_sids);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("fill_grent_mem_domain_users: "
- "lookup_usergroups failed "
- "for sid %s in domain %s (error: %s)\n",
+ DEBUG(1, ("fill_grent_mem_domain_users: lookup_usergroups failed "
+ "for sid %s in domain %s (error: %s)\n",
sid_string_dbg(pquerying_user_sid),
domain->name,
nt_errstr(status)));
- return False;
+ return False;
}
for (i = 0; i < num_groups; i++) {
@@ -294,22 +269,18 @@ static bool fill_grent_mem_domusers( TALLOC_CTX *mem_ctx,
}
}
}
-
+
if (u_in_group) {
size_t len = 0;
char *domainname = NULL;
char *username = NULL;
fstring name;
- char *mapped_name = NULL;
enum lsa_SidType type;
- struct winbindd_domain *target_domain = NULL;
- NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(10,("fill_grent_mem_domain_users: "
- "sid %s in 'Domain Users' in domain %s\n",
+
+ DEBUG(10,("fill_grent_mem_domain_users: sid %s in 'Domain Users' in domain %s\n",
sid_string_dbg(pquerying_user_sid),
domain->name ));
-
+
status = domain->methods->sid_to_name(domain, mem_ctx,
pquerying_user_sid,
&domainname,
@@ -317,56 +288,38 @@ static bool fill_grent_mem_domusers( TALLOC_CTX *mem_ctx,
&type);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("could not lookup username for user "
- "sid %s in domain %s (error: %s)\n",
+ "sid %s in domain %s (error: %s)\n",
sid_string_dbg(pquerying_user_sid),
domain->name,
nt_errstr(status)));
- return False;
- }
-
- target_domain = find_domain_from_name_noinit(domainname);
- name_map_status = normalize_name_map(mem_ctx, target_domain,
- username, &mapped_name);
-
- /* Basic whitespace replacement */
- if (NT_STATUS_IS_OK(name_map_status)) {
- fill_domain_username(name, domainname, mapped_name, true);
- }
- /* Mapped to an alias */
- else if (NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) {
- fstrcpy(name, mapped_name);
- }
- /* no mapping done...use original name */
- else {
- fill_domain_username(name, domainname, username, true);
+ return False;
}
-
+ fill_domain_username(name, domain->name, username, True);
len = strlen(name);
buf_len = len + 1;
if (!(buf = (char *)SMB_MALLOC(buf_len))) {
DEBUG(1, ("out of memory\n"));
- return False;
+ return False;
}
memcpy(buf, name, buf_len);
-
+
DEBUG(10,("fill_grent_mem_domain_users: user %s in "
"'Domain Users' in domain %s\n",
name, domain->name ));
-
+
/* user is the only member */
*num_gr_mem = 1;
}
-
+
*gr_mem = buf;
*gr_mem_len = buf_len;
-
- DEBUG(10, ("fill_grent_mem_domain_users: "
- "num_mem = %u, len = %u, mem = %s\n",
- (unsigned int)*num_gr_mem,
- (unsigned int)buf_len, *num_gr_mem ? buf : "NULL"));
+
+ DEBUG(10, ("fill_grent_mem_domain_users: num_mem = %u, len = %u, mem = %s\n",
+ (unsigned int)*num_gr_mem,
+ (unsigned int)buf_len, *num_gr_mem ? buf : "NULL"));
return True;
-}
+}
/***********************************************************************
Add names to a list. Assumes a canonical version of the string
@@ -375,29 +328,28 @@ static bool fill_grent_mem_domusers( TALLOC_CTX *mem_ctx,
static int namecmp( const void *a, const void *b )
{
- return StrCaseCmp( * (char * const *) a, * (char * const *) b);
+ return StrCaseCmp( * (char * const *) a, * (char * const *) b);
}
-static NTSTATUS add_names_to_list( TALLOC_CTX *ctx,
- char ***list, uint32 *n_list,
+static NTSTATUS add_names_to_list( TALLOC_CTX *ctx,
+ char ***list, uint32 *n_list,
char **names, uint32 n_names )
{
- char **new_list = NULL;
- uint32 n_new_list = 0;
- int i, j;
+ char **new_list = NULL;
+ uint32 n_new_list = 0;
+ int i, j;
if ( !names || (n_names == 0) )
return NT_STATUS_OK;
-
+
/* Alloc the maximum size we'll need */
if ( *list == NULL ) {
- if ((new_list = TALLOC_ARRAY(ctx, char *, n_names)) == NULL) {
+ if ( (new_list = TALLOC_ARRAY( ctx, char *, n_names )) == NULL )
return NT_STATUS_NO_MEMORY;
- }
- n_new_list = n_names;
+ n_new_list = n_names;
} else {
- new_list = TALLOC_REALLOC_ARRAY( ctx, *list, char *,
+ new_list = TALLOC_REALLOC_ARRAY( ctx, *list, char *,
(*n_list) + n_names );
if ( !new_list )
return NT_STATUS_NO_MEMORY;
@@ -412,33 +364,33 @@ static NTSTATUS add_names_to_list( TALLOC_CTX *ctx,
/* search for duplicates for sorting and looking for matching
neighbors */
-
+
qsort( new_list, n_new_list, sizeof(char*), QSORT_CAST namecmp );
-
+
for ( i=1; i<n_new_list; i++ ) {
- if ( strcmp( new_list[i-1], new_list[i] ) == 0 ) {
- memmove( &new_list[i-1], &new_list[i],
+ if ( strcmp( new_list[i-1], new_list[i] ) == 0 ) {
+ memmove( &new_list[i-1], &new_list[i],
sizeof(char*)*(n_new_list-i) );
n_new_list--;
}
}
*list = new_list;
- *n_list = n_new_list;
+ *n_list = n_new_list;
- return NT_STATUS_OK;
+ return NT_STATUS_OK;
}
/***********************************************************************
***********************************************************************/
-static NTSTATUS expand_groups( TALLOC_CTX *ctx,
+static NTSTATUS expand_groups( TALLOC_CTX *ctx,
struct winbindd_domain *d,
DOM_SID *glist, uint32 n_glist,
DOM_SID **new_glist, uint32 *n_new_glist,
char ***members, uint32 *n_members )
{
- int i, j;
+ int i, j;
NTSTATUS status = NT_STATUS_OK;
uint32 num_names = 0;
uint32 *name_types = NULL;
@@ -446,25 +398,25 @@ static NTSTATUS expand_groups( TALLOC_CTX *ctx,
DOM_SID *sid_mem = NULL;
TALLOC_CTX *tmp_ctx = NULL;
DOM_SID *new_groups = NULL;
- size_t new_groups_size = 0;
-
+ size_t new_groups_size = 0;
+
*members = NULL;
- *n_members = 0;
+ *n_members = 0;
*new_glist = NULL;
- *n_new_glist = 0;
-
+ *n_new_glist = 0;
+
for ( i=0; i<n_glist; i++ ) {
tmp_ctx = talloc_new( ctx );
/* Lookup the group membership */
- status = d->methods->lookup_groupmem(d, tmp_ctx,
+ status = d->methods->lookup_groupmem(d, tmp_ctx,
&glist[i], &num_names,
- &sid_mem, &names,
+ &sid_mem, &names,
&name_types);
- if ( !NT_STATUS_IS_OK(status) )
+ if ( !NT_STATUS_IS_OK(status) )
goto out;
-
+
/* Separate users and groups into two lists */
for ( j=0; j<num_names; j++ ) {
@@ -473,14 +425,14 @@ static NTSTATUS expand_groups( TALLOC_CTX *ctx,
if ( name_types[j] == SID_NAME_USER ||
name_types[j] == SID_NAME_COMPUTER )
{
- status = add_names_to_list( ctx, members,
+ status = add_names_to_list( ctx, members,
n_members,
names+j, 1 );
if ( !NT_STATUS_IS_OK(status) )
goto out;
- continue;
- }
+ continue;
+ }
/* Groups */
if ( name_types[j] == SID_NAME_DOM_GRP ||
@@ -502,12 +454,12 @@ static NTSTATUS expand_groups( TALLOC_CTX *ctx,
}
*new_glist = new_groups;
- *n_new_glist = (uint32)new_groups_size;
-
+ *n_new_glist = (uint32)new_groups_size;
+
out:
TALLOC_FREE( tmp_ctx );
-
- return status;
+
+ return status;
}
/***********************************************************************
@@ -516,10 +468,9 @@ static NTSTATUS expand_groups( TALLOC_CTX *ctx,
static bool fill_grent_mem(struct winbindd_domain *domain,
struct winbindd_cli_state *state,
- DOM_SID *group_sid,
- enum lsa_SidType group_name_type,
- size_t *num_gr_mem, char **gr_mem,
- size_t *gr_mem_len)
+ DOM_SID *group_sid,
+ enum lsa_SidType group_name_type,
+ size_t *num_gr_mem, char **gr_mem, size_t *gr_mem_len)
{
uint32 num_names = 0;
unsigned int buf_len = 0, buf_ndx = 0, i;
@@ -529,8 +480,8 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
uint32 group_rid;
DOM_SID *glist = NULL;
DOM_SID *new_glist = NULL;
- uint32 n_glist, n_new_glist;
- int max_depth = lp_winbind_expand_groups();
+ uint32 n_glist, n_new_glist;
+ int max_depth = lp_winbind_expand_groups();
if (!(mem_ctx = talloc_init("fill_grent_mem(%s)", domain->name)))
return False;
@@ -557,7 +508,7 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
if ( !((group_name_type==SID_NAME_DOM_GRP) ||
((group_name_type==SID_NAME_ALIAS) && domain->primary)) )
{
- DEBUG(1, ("SID %s in domain %s isn't a domain group (%d)\n",
+ DEBUG(1, ("SID %s in domain %s isn't a domain group (%d)\n",
sid_string_dbg(group_sid),
domain->name, group_name_type));
goto done;
@@ -568,15 +519,15 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
sid_peek_rid( group_sid, &group_rid );
if (!lp_winbind_enum_users() && group_rid == DOMAIN_GROUP_RID_USERS) {
- result = fill_grent_mem_domusers( mem_ctx, domain, state,
+ result = fill_grent_mem_domusers( mem_ctx, domain, state,
group_sid, group_name_type,
num_gr_mem, gr_mem,
gr_mem_len );
- goto done;
+ goto done;
}
/* Real work goes here. Create a list of group names to
- expand startign with the initial one. Pass that to
+ expand startign with the initial one. Pass that to
expand_groups() which returns a list of more group names
to expand. Do this up to the max search depth. */
@@ -585,66 +536,33 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
DEBUG(0,("fill_grent_mem: talloc failure!\n"));
goto done;
}
- sid_copy( &glist[0], group_sid );
- n_glist = 1;
+ sid_copy( &glist[0], group_sid );
+ n_glist = 1;
for ( i=0; i<max_depth && glist; i++ ) {
uint32 n_members = 0;
char **members = NULL;
- NTSTATUS nt_status;
- int j;
+ NTSTATUS nt_status;
nt_status = expand_groups( mem_ctx, domain,
- glist, n_glist,
+ glist, n_glist,
&new_glist, &n_new_glist,
&members, &n_members);
if ( !NT_STATUS_IS_OK(nt_status) ) {
- result = False;
+ result = False;
goto done;
- }
+ }
+
+ /* Add new group members to list */
- /* Add new group members to list. Pass through the
- alias mapping function */
-
- for (j=0; j<n_members; j++) {
- fstring name_domain, name_acct;
- fstring qualified_name;
- char *mapped_name = NULL;
- NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
- struct winbindd_domain *target_domain = NULL;
-
- if (parse_domain_user(members[j], name_domain, name_acct)) {
- target_domain = find_domain_from_name_noinit(name_domain);
- /* NOW WHAT ? */
- }
- if (!target_domain) {
- target_domain = domain;
- }
-
- name_map_status = normalize_name_map(members, target_domain,
- name_acct, &mapped_name);
-
- /* Basic whitespace replacement */
- if (NT_STATUS_IS_OK(name_map_status)) {
- fill_domain_username(qualified_name, name_domain,
- mapped_name, true);
- mapped_name = qualified_name;
- }
- /* no mapping at all */
- else if (!NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) {
- mapped_name = members[j];
- }
-
- nt_status = add_names_to_list( mem_ctx, &names,
- &num_names,
- &mapped_name, 1);
- if ( !NT_STATUS_IS_OK(nt_status) ) {
- result = False;
- goto done;
- }
+ nt_status = add_names_to_list( mem_ctx, &names, &num_names,
+ members, n_members );
+ if ( !NT_STATUS_IS_OK(nt_status) ) {
+ result = False;
+ goto done;
}
-
- TALLOC_FREE( members );
+
+ TALLOC_FREE( members );
/* If we have no more groups to expand, break out
early */
@@ -657,8 +575,8 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
glist = new_glist;
n_glist = n_new_glist;
}
- TALLOC_FREE( glist );
-
+ TALLOC_FREE( glist );
+
DEBUG(10, ("looked up %d names\n", num_names));
again:
@@ -666,11 +584,11 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
for (i = 0; i < num_names; i++) {
int len;
-
+
DEBUG(10, ("processing name %s\n", names[i]));
len = strlen(names[i]);
-
+
/* Add to list or calculate buffer length */
if (!buf) {
@@ -708,27 +626,26 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
*gr_mem = buf;
*gr_mem_len = buf_len;
- DEBUG(10, ("num_mem = %u, len = %u, mem = %s\n",
- (unsigned int)*num_gr_mem,
- (unsigned int)buf_len, *num_gr_mem ? buf : "NULL"));
+ DEBUG(10, ("num_mem = %u, len = %u, mem = %s\n", (unsigned int)*num_gr_mem,
+ (unsigned int)buf_len, *num_gr_mem ? buf : "NULL"));
result = True;
done:
talloc_destroy(mem_ctx);
-
+
DEBUG(10, ("fill_grent_mem returning %d\n", result));
return result;
}
-static void winbindd_getgrsid(struct winbindd_cli_state *state, DOM_SID group_sid);
+static void winbindd_getgrsid( struct winbindd_cli_state *state, DOM_SID group_sid );
-static void getgrnam_recv( void *private_data, bool success, const DOM_SID *sid,
+static void getgrnam_recv( void *private_data, bool success, const DOM_SID *sid,
enum lsa_SidType type )
{
struct winbindd_cli_state *state = (struct winbindd_cli_state*)private_data;
-
+
if (!success) {
DEBUG(5,("getgrnam_recv: lookupname failed!\n"));
request_error(state);
@@ -739,12 +656,12 @@ static void getgrnam_recv( void *private_data, bool success, const DOM_SID *sid,
DEBUG(5,("getgrnam_recv: not a group!\n"));
request_error(state);
return;
- }
+ }
winbindd_getgrsid( state, *sid );
}
-
+
/* Return a group structure from a group name */
void winbindd_getgrnam(struct winbindd_cli_state *state)
@@ -752,32 +669,22 @@ void winbindd_getgrnam(struct winbindd_cli_state *state)
struct winbindd_domain *domain;
fstring name_domain, name_group;
char *tmp;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
+
/* Ensure null termination */
state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0';
DEBUG(3, ("[%5lu]: getgrnam %s\n", (unsigned long)state->pid,
state->request.data.groupname));
- nt_status = normalize_name_unmap(state->mem_ctx,
- state->request.data.groupname,
- &tmp);
- /* If we didn't map anything in the above call, just reset the
- tmp pointer to the original string */
- if (!NT_STATUS_IS_OK(nt_status) &&
- !NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
- {
- tmp = state->request.data.groupname;
- }
-
/* Parse domain and groupname */
+
+ memset(name_group, 0, sizeof(fstring));
- memset(name_group, 0, sizeof(name_group));
+ tmp = state->request.data.groupname;
name_domain[0] = '\0';
name_group[0] = '\0';
-
+
parse_domain_user(tmp, name_domain, name_group);
/* if no domain or our local domain and no local tdb group, default to
@@ -796,7 +703,7 @@ void winbindd_getgrnam(struct winbindd_cli_state *state)
return;
}
/* should we deal with users for our domain? */
-
+
if ( lp_winbind_trusted_domains_only() && domain->primary) {
DEBUG(7,("winbindd_getgrnam: My domain -- rejecting "
"getgrnam() for %s\\%s.\n", name_domain, name_group));
@@ -806,8 +713,8 @@ void winbindd_getgrnam(struct winbindd_cli_state *state)
/* Get rid and name type from name */
- fstrcpy( name_group, tmp );
-
+ ws_name_replace( name_group, WB_REPLACE_CHAR );
+
winbindd_lookupname_async( state->mem_ctx, domain->name, name_group,
getgrnam_recv, WINBINDD_GETGRNAM, state );
}
@@ -816,7 +723,7 @@ struct getgrsid_state {
struct winbindd_cli_state *state;
struct winbindd_domain *domain;
char *group_name;
- enum lsa_SidType group_type;
+ enum lsa_SidType group_type;
uid_t gid;
DOM_SID group_sid;
};
@@ -829,7 +736,7 @@ static void getgrsid_sid2gid_recv(void *private_data, bool success, gid_t gid)
size_t gr_mem_len;
size_t num_gr_mem;
char *gr_mem;
- fstring dom_name, group_name;
+ fstring dom_name, group_name;
if (!success) {
DEBUG(5,("getgrsid_sid2gid_recv: sid2gid failed!\n"));
@@ -845,7 +752,7 @@ static void getgrsid_sid2gid_recv(void *private_data, bool success, gid_t gid)
return;
}
-
+
/* Fill in group structure */
if ( (domain = find_domain_from_name_noinit(dom_name)) == NULL ) {
@@ -854,10 +761,9 @@ static void getgrsid_sid2gid_recv(void *private_data, bool success, gid_t gid)
return;
}
- if (!fill_grent(s->state->mem_ctx, &s->state->response.data.gr,
- dom_name, group_name, gid) ||
+ if (!fill_grent(&s->state->response.data.gr, dom_name, group_name, gid) ||
!fill_grent_mem(domain, s->state, &s->group_sid, s->group_type,
- &num_gr_mem, &gr_mem, &gr_mem_len))
+ &num_gr_mem, &gr_mem, &gr_mem_len))
{
request_error(s->state);
return;
@@ -872,7 +778,7 @@ static void getgrsid_sid2gid_recv(void *private_data, bool success, gid_t gid)
s->state->response.length += gr_mem_len;
s->state->response.extra_data.data = gr_mem;
- request_ok(s->state);
+ request_ok(s->state);
}
static void getgrsid_lookupsid_recv( void *private_data, bool success,
@@ -880,9 +786,6 @@ static void getgrsid_lookupsid_recv( void *private_data, bool success,
enum lsa_SidType name_type )
{
struct getgrsid_state *s = (struct getgrsid_state *)private_data;
- char *mapped_name = NULL;
- fstring raw_name;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
if (!success) {
DEBUG(5,("getgrsid_lookupsid_recv: lookupsid failed!\n"));
@@ -894,46 +797,22 @@ static void getgrsid_lookupsid_recv( void *private_data, bool success,
local group in an internal domain */
if ( !( (name_type==SID_NAME_DOM_GRP) ||
- ((name_type==SID_NAME_ALIAS) &&
+ ((name_type==SID_NAME_ALIAS) &&
(s->domain->primary || s->domain->internal)) ) )
{
- DEBUG(1, ("name '%s\\%s' is not a local or domain group: %d\n",
+ DEBUG(1, ("name '%s\\%s' is not a local or domain group: %d\n",
dom_name, name, name_type));
request_error(s->state);
return;
- }
-
- /* normalize the name and ensure that we have the DOM\name
- coming out of here */
-
- fstrcpy(raw_name, name);
-
- nt_status = normalize_name_unmap(s->state->mem_ctx, raw_name,
- &mapped_name);
-
- /* basiuc whitespace reversal */
- if (NT_STATUS_IS_OK(nt_status)) {
- s->group_name = talloc_asprintf(s->state->mem_ctx,
- "%s%c%s",
- dom_name,
- *lp_winbind_separator(),
- mapped_name);
- }
- /* mapped from alias */
- else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) {
- s->group_name = mapped_name;
- }
- /* no mapping at all. use original string */
- else {
- s->group_name = talloc_asprintf(s->state->mem_ctx,
- "%s%c%s",
- dom_name,
- *lp_winbind_separator(),
- raw_name);
- }
+}
- if (s->group_name == NULL) {
- DEBUG(1, ("getgrsid_lookupsid_recv: group_name is NULL!\n"));
+ if ( (s->group_name = talloc_asprintf( s->state->mem_ctx,
+ "%s%c%s",
+ dom_name,
+ *lp_winbind_separator(),
+ name)) == NULL )
+{
+ DEBUG(1, ("getgrsid_lookupsid_recv: talloc_asprintf() Failed!\n"));
request_error(s->state);
return;
}
@@ -942,10 +821,10 @@ static void getgrsid_lookupsid_recv( void *private_data, bool success,
winbindd_sid2gid_async(s->state->mem_ctx, &s->group_sid,
getgrsid_sid2gid_recv, s);
-}
+ }
static void winbindd_getgrsid( struct winbindd_cli_state *state, const DOM_SID group_sid )
-{
+ {
struct getgrsid_state *s;
if ( (s = TALLOC_ZERO_P(state->mem_ctx, struct getgrsid_state)) == NULL ) {
@@ -965,7 +844,7 @@ static void winbindd_getgrsid( struct winbindd_cli_state *state, const DOM_SID g
sid_copy(&s->group_sid, &group_sid);
- winbindd_lookupsid_async( s->state->mem_ctx, &group_sid,
+ winbindd_lookupsid_async( s->state->mem_ctx, &group_sid,
getgrsid_lookupsid_recv, s );
}
@@ -996,7 +875,7 @@ static void getgrgid_recv(void *private_data, bool success, const char *sid)
return;
}
- DEBUG(1, ("could not convert gid %lu to sid\n",
+ DEBUG(1, ("could not convert gid %lu to sid\n",
(unsigned long)state->request.data.gid));
request_error(state);
}
@@ -1004,14 +883,11 @@ static void getgrgid_recv(void *private_data, bool success, const char *sid)
/* Return a group structure from a gid number */
void winbindd_getgrgid(struct winbindd_cli_state *state)
{
- gid_t gid = state->request.data.gid;
-
- DEBUG(3, ("[%5lu]: getgrgid %lu\n",
- (unsigned long)state->pid,
- (unsigned long)gid));
+ DEBUG(3, ("[%5lu]: getgrgid %lu\n", (unsigned long)state->pid,
+ (unsigned long)state->request.data.gid));
/* always use the async interface */
- winbindd_gid2sid_async(state->mem_ctx, gid, getgrgid_recv, state);
+ winbindd_gid2sid_async(state->mem_ctx, state->request.data.gid, getgrgid_recv, state);
}
/*
@@ -1030,46 +906,45 @@ static bool winbindd_setgrent_internal(struct winbindd_cli_state *state)
if (!lp_winbind_enum_groups()) {
return False;
- }
+ }
/* Free old static data if it exists */
-
+
if (state->getgrent_state != NULL) {
free_getent_state(state->getgrent_state);
state->getgrent_state = NULL;
}
-
+
/* Create sam pipes for each domain we know about */
-
+
for (domain = domain_list(); domain != NULL; domain = domain->next) {
struct getent_state *domain_state;
-
+
/* Create a state record for this domain */
- /* don't add our domaina if we are a PDC or if we
+ /* don't add our domaina if we are a PDC or if we
are a member of a Samba domain */
-
+
if ( lp_winbind_trusted_domains_only() && domain->primary )
{
continue;
}
-
- domain_state = SMB_MALLOC_P(struct getent_state);
- if (!domain_state) {
- DEBUG(1, ("winbindd_setgrent: "
- "malloc failed for domain_state!\n"));
+
+
+ if ((domain_state = SMB_MALLOC_P(struct getent_state)) == NULL) {
+ DEBUG(1, ("winbindd_setgrent: malloc failed for domain_state!\n"));
return False;
}
-
+
ZERO_STRUCTP(domain_state);
-
+
fstrcpy(domain_state->domain_name, domain->name);
/* Add to list of open domains */
-
+
DLIST_ADD(state->getgrent_state, domain_state);
}
-
+
state->getgrent_initialized = True;
return True;
}
@@ -1096,7 +971,7 @@ void winbindd_endgrent(struct winbindd_cli_state *state)
}
/* Get the list of domain groups and domain aliases for a domain. We fill in
- the sam_entries and num_sam_entries fields with domain group information.
+ the sam_entries and num_sam_entries fields with domain group information.
Return True if some groups were returned, False otherwise. */
bool get_sam_group_entries(struct getent_state *ent)
@@ -1108,17 +983,16 @@ bool get_sam_group_entries(struct getent_state *ent)
bool result = False;
struct acct_info *sam_grp_entries = NULL;
struct winbindd_domain *domain;
-
+
if (ent->got_sam_entries)
return False;
if (!(mem_ctx = talloc_init("get_sam_group_entries(%s)",
ent->domain_name))) {
- DEBUG(1, ("get_sam_group_entries: "
- "could not create talloc context!\n"));
+ DEBUG(1, ("get_sam_group_entries: could not create talloc context!\n"));
return False;
}
-
+
/* Free any existing group info */
SAFE_FREE(ent->sam_entries);
@@ -1130,20 +1004,16 @@ bool get_sam_group_entries(struct getent_state *ent)
num_entries = 0;
if (!(domain = find_domain_from_name(ent->domain_name))) {
- DEBUG(3, ("no such domain %s in get_sam_group_entries\n",
- ent->domain_name));
+ DEBUG(3, ("no such domain %s in get_sam_group_entries\n", ent->domain_name));
goto done;
}
/* always get the domain global groups */
- status = domain->methods->enum_dom_groups(domain, mem_ctx, &num_entries,
- &sam_grp_entries);
-
+ status = domain->methods->enum_dom_groups(domain, mem_ctx, &num_entries, &sam_grp_entries);
+
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("get_sam_group_entries: "
- "could not enumerate domain groups! Error: %s\n",
- nt_errstr(status)));
+ DEBUG(3, ("get_sam_group_entries: could not enumerate domain groups! Error: %s\n", nt_errstr(status)));
result = False;
goto done;
}
@@ -1151,36 +1021,29 @@ bool get_sam_group_entries(struct getent_state *ent)
/* Copy entries into return buffer */
if (num_entries) {
- name_list = SMB_MALLOC_ARRAY(struct acct_info, num_entries);
- if (!name_list) {
- DEBUG(0,("get_sam_group_entries: Failed to malloc "
- "memory for %d domain groups!\n",
- num_entries));
+ if ( !(name_list = SMB_MALLOC_ARRAY(struct acct_info, num_entries)) ) {
+ DEBUG(0,("get_sam_group_entries: Failed to malloc memory for %d domain groups!\n",
+ num_entries));
result = False;
goto done;
}
- memcpy(name_list, sam_grp_entries,
- num_entries * sizeof(struct acct_info));
+ memcpy( name_list, sam_grp_entries, num_entries * sizeof(struct acct_info) );
}
-
+
ent->num_sam_entries = num_entries;
-
- /* get the domain local groups if we are a member of a native win2k
- * domain and are not using LDAP to get the groups */
-
- if ( ( lp_security() != SEC_ADS && domain->native_mode
+
+ /* get the domain local groups if we are a member of a native win2k domain
+ and are not using LDAP to get the groups */
+
+ if ( ( lp_security() != SEC_ADS && domain->native_mode
&& domain->primary) || domain->internal )
{
- DEBUG(4,("get_sam_group_entries: %s domain; "
- "enumerating local groups as well\n",
- domain->native_mode ? "Native Mode 2k":
- "BUILTIN or local"));
-
- status = domain->methods->enum_local_groups(domain, mem_ctx,
- &num_entries,
- &sam_grp_entries);
-
- if ( !NT_STATUS_IS_OK(status) ) {
+ DEBUG(4,("get_sam_group_entries: %s domain; enumerating local groups as well\n",
+ domain->native_mode ? "Native Mode 2k":"BUILTIN or local"));
+
+ status = domain->methods->enum_local_groups(domain, mem_ctx, &num_entries, &sam_grp_entries);
+
+ if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(3,("get_sam_group_entries: "
"Failed to enumerate "
"domain local groups with error %s!\n",
@@ -1188,35 +1051,27 @@ bool get_sam_group_entries(struct getent_state *ent)
num_entries = 0;
}
else
- DEBUG(4,("get_sam_group_entries: "
- "Returned %d local groups\n",
- num_entries));
-
+ DEBUG(4,("get_sam_group_entries: Returned %d local groups\n", num_entries));
+
/* Copy entries into return buffer */
if ( num_entries ) {
- name_list = SMB_REALLOC_ARRAY(name_list,
- struct acct_info,
- ent->num_sam_entries+
- num_entries);
- if (!name_list) {
- DEBUG(0,("get_sam_group_entries: "
- "Failed to realloc more memory "
- "for %d local groups!\n",
- num_entries));
+ if ( !(name_list = SMB_REALLOC_ARRAY( name_list, struct acct_info, ent->num_sam_entries+num_entries)) )
+ {
+ DEBUG(0,("get_sam_group_entries: Failed to realloc more memory for %d local groups!\n",
+ num_entries));
result = False;
goto done;
}
-
- memcpy(&name_list[ent->num_sam_entries],
- sam_grp_entries,
- num_entries * sizeof(struct acct_info));
+
+ memcpy( &name_list[ent->num_sam_entries], sam_grp_entries,
+ num_entries * sizeof(struct acct_info) );
}
-
+
ent->num_sam_entries += num_entries;
}
-
-
+
+
/* Fill in remaining fields */
ent->sam_entries = name_list;
@@ -1257,19 +1112,18 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
return;
}
- group_list = SMB_MALLOC_ARRAY(struct winbindd_gr, num_groups);
- if (!group_list) {
+ if ((state->response.extra_data.data = SMB_MALLOC_ARRAY(struct winbindd_gr, num_groups)) == NULL) {
request_error(state);
return;
}
- /* will be freed by process_request() */
- state->response.extra_data.data = group_list;
memset(state->response.extra_data.data, '\0',
num_groups * sizeof(struct winbindd_gr) );
state->response.data.num_entries = 0;
+ group_list = (struct winbindd_gr *)state->response.extra_data.data;
+
if (!state->getgrent_initialized)
winbindd_setgrent_internal(state);
@@ -1289,7 +1143,7 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
char *gr_mem;
DOM_SID group_sid;
struct winbindd_domain *domain;
-
+
/* Do we need to fetch another chunk of groups? */
tryagain:
@@ -1302,8 +1156,7 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
while(ent && !get_sam_group_entries(ent)) {
struct getent_state *next_ent;
- DEBUG(10, ("freeing state info for domain %s\n",
- ent->domain_name));
+ DEBUG(10, ("freeing state info for domain %s\n", ent->domain_name));
/* Free state information for this domain */
@@ -1311,33 +1164,32 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
next_ent = ent->next;
DLIST_REMOVE(state->getgrent_state, ent);
-
+
SAFE_FREE(ent);
ent = next_ent;
}
/* No more domains */
- if (!ent)
+ if (!ent)
break;
}
-
+
name_list = (struct acct_info *)ent->sam_entries;
-
- if (!(domain = find_domain_from_name(ent->domain_name))) {
- DEBUG(3, ("No such domain %s in winbindd_getgrent\n",
- ent->domain_name));
+
+ if (!(domain =
+ find_domain_from_name(ent->domain_name))) {
+ DEBUG(3, ("No such domain %s in winbindd_getgrent\n", ent->domain_name));
result = False;
goto done;
}
/* Lookup group info */
-
+
sid_copy(&group_sid, &domain->sid);
sid_append_rid(&group_sid, name_list[ent->sam_entry_index].rid);
- if (!NT_STATUS_IS_OK(idmap_sid_to_gid(domain->name, &group_sid,
- &group_gid))) {
+ if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &group_gid))) {
union unid_t id;
enum lsa_SidType type;
@@ -1345,8 +1197,9 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
sid_string_dbg(&group_sid)));
if (!pdb_sid_to_id(&group_sid, &id, &type)) {
- DEBUG(1,("could not look up gid for group %s\n",
- name_list[ent->sam_entry_index].acct_name));
+ DEBUG(1, ("could not look up gid for group "
+ "%s\n",
+ name_list[ent->sam_entry_index].acct_name));
ent->sam_entry_index++;
goto tryagain;
}
@@ -1363,16 +1216,15 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
group_gid = id.gid;
}
- DEBUG(10, ("got gid %lu for group %lu\n",
- (unsigned long)group_gid,
+ DEBUG(10, ("got gid %lu for group %lu\n", (unsigned long)group_gid,
(unsigned long)name_list[ent->sam_entry_index].rid));
-
+
/* Fill in group entry */
- fill_domain_username(domain_group_name, ent->domain_name,
+ fill_domain_username(domain_group_name, ent->domain_name,
name_list[ent->sam_entry_index].acct_name, True);
- result = fill_grent(state->mem_ctx, &group_list[group_list_ndx],
+ result = fill_grent(&group_list[group_list_ndx],
ent->domain_name,
name_list[ent->sam_entry_index].acct_name,
group_gid);
@@ -1385,8 +1237,8 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
group_list[group_list_ndx].num_gr_mem = 0;
gr_mem = NULL;
gr_mem_len = 0;
-
- /* Get group membership */
+
+ /* Get group membership */
if (state->request.cmd == WINBINDD_GETGRLST) {
result = True;
} else {
@@ -1409,8 +1261,7 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
gr_mem_list = (char *)SMB_REALLOC(
gr_mem_list, gr_mem_list_len + gr_mem_len);
- if (!gr_mem_list &&
- (group_list[group_list_ndx].num_gr_mem != 0)) {
+ if (!gr_mem_list && (group_list[group_list_ndx].num_gr_mem != 0)) {
DEBUG(0, ("out of memory\n"));
gr_mem_list_len = 0;
break;
@@ -1424,16 +1275,16 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
SAFE_FREE(gr_mem);
- group_list[group_list_ndx].gr_mem_ofs =
+ group_list[group_list_ndx].gr_mem_ofs =
gr_mem_list_len;
gr_mem_list_len += gr_mem_len;
}
ent->sam_entry_index++;
-
+
/* Add group to return list */
-
+
if (result) {
DEBUG(10, ("adding group num_entries = %d\n",
@@ -1441,12 +1292,12 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
group_list_ndx++;
state->response.data.num_entries++;
-
+
state->response.length +=
sizeof(struct winbindd_gr);
-
+
} else {
- DEBUG(0, ("could not lookup domain group %s\n",
+ DEBUG(0, ("could not lookup domain group %s\n",
domain_group_name));
}
}
@@ -1469,7 +1320,7 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
}
memcpy(&((char *)state->response.extra_data.data)
- [group_list_ndx * sizeof(struct winbindd_gr)],
+ [group_list_ndx * sizeof(struct winbindd_gr)],
gr_mem_list, gr_mem_list_len);
state->response.length += gr_mem_list_len;
@@ -1524,8 +1375,6 @@ static void getgroups_sid2gid_recv(void *private_data, bool success, gid_t gid);
void winbindd_getgroups(struct winbindd_cli_state *state)
{
struct getgroups_state *s;
- char *real_name = NULL;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
/* Ensure null termination */
state->request.data.username
@@ -1545,22 +1394,13 @@ void winbindd_getgroups(struct winbindd_cli_state *state)
s->state = state;
- nt_status = normalize_name_unmap(state->mem_ctx,
- state->request.data.username,
- &real_name);
+ ws_name_return( state->request.data.username, WB_REPLACE_CHAR );
- /* Reset the real_name pointer if we didn't do anything
- productive in the above call */
- if (!NT_STATUS_IS_OK(nt_status) &&
- !NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
- {
- real_name = state->request.data.username;
- }
-
- if (!parse_domain_user_talloc(state->mem_ctx, real_name,
+ if (!parse_domain_user_talloc(state->mem_ctx,
+ state->request.data.username,
&s->domname, &s->username)) {
DEBUG(5, ("Could not parse domain user: %s\n",
- real_name));
+ state->request.data.username));
/* error out if we do not have nested group support */
@@ -1569,27 +1409,25 @@ void winbindd_getgroups(struct winbindd_cli_state *state)
return;
}
- s->domname = talloc_strdup(state->mem_ctx,
- get_global_sam_name());
- s->username = talloc_strdup(state->mem_ctx,
- state->request.data.username);
+ s->domname = talloc_strdup( state->mem_ctx, get_global_sam_name() );
+ s->username = talloc_strdup( state->mem_ctx, state->request.data.username );
}
-
- /* Get info for the domain (either by short domain name or
+
+ /* Get info for the domain (either by short domain name or
DNS name in the case of a UPN) */
s->domain = find_domain_from_name_noinit(s->domname);
if (!s->domain) {
char *p = strchr(s->username, '@');
-
+
if (p) {
- s->domain = find_domain_from_name_noinit(p+1);
+ s->domain = find_domain_from_name_noinit(p+1);
}
-
+
}
if (s->domain == NULL) {
- DEBUG(7, ("could not find domain entry for domain %s\n",
+ DEBUG(7, ("could not find domain entry for domain %s\n",
s->domname));
request_error(state);
return;
@@ -1601,14 +1439,12 @@ void winbindd_getgroups(struct winbindd_cli_state *state)
s->username));
request_error(state);
return;
- }
+ }
/* Get rid and name type from name. The following costs 1 packet */
- winbindd_lookupname_async(state->mem_ctx,
- s->domname, s->username,
- getgroups_usersid_recv,
- WINBINDD_GETGROUPS, s);
+ winbindd_lookupname_async(state->mem_ctx, s->domname, s->username,
+ getgroups_usersid_recv, WINBINDD_GETGROUPS, s);
}
static void getgroups_usersid_recv(void *private_data, bool success,
@@ -1683,9 +1519,7 @@ static void getgroups_sid2gid_recv(void *private_data, bool success, gid_t gid)
s->state->response.data.num_entries = s->num_token_gids;
if (s->num_token_gids) {
/* s->token_gids are talloced */
- s->state->response.extra_data.data =
- smb_xmemdup(s->token_gids,
- s->num_token_gids * sizeof(gid_t));
+ s->state->response.extra_data.data = smb_xmemdup(s->token_gids, s->num_token_gids * sizeof(gid_t));
s->state->response.length += s->num_token_gids * sizeof(gid_t);
}
request_ok(s->state);
@@ -1696,7 +1530,7 @@ static void getgroups_sid2gid_recv(void *private_data, bool success, gid_t gid)
rather than a NAME->SID->SIDS->GIDS mapping, which means we avoid
idmap. This call is designed to be used with applications that need
to do ACL evaluation themselves. Note that the cached info3 data is
- not used
+ not used
this function assumes that the SID that comes in is a user SID. If
you pass in another type of SID then you may get unpredictable
@@ -1789,9 +1623,9 @@ void winbindd_getuserdomgroups(struct winbindd_cli_state *state)
return;
}
- /* Get info for the domain */
+ /* Get info for the domain */
if ((domain = find_domain_from_sid_noinit(&user_sid)) == NULL) {
- DEBUG(0,("could not find domain entry for sid %s\n",
+ DEBUG(0,("could not find domain entry for sid %s\n",
sid_string_dbg(&user_sid)));
request_error(state);
return;
@@ -1832,9 +1666,7 @@ enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *doma
return WINBINDD_OK;
}
- if (!print_sidlist(state->mem_ctx,
- groups, num_groups,
- &sidstring, &len)) {
+ if (!print_sidlist(state->mem_ctx, groups, num_groups, &sidstring, &len)) {
DEBUG(0, ("talloc failed\n"));
return WINBINDD_ERROR;
}
diff --git a/source/winbindd/winbindd_idmap.c b/source/winbindd/winbindd_idmap.c
index d8c67dc21c..3c7aa2d0c2 100644
--- a/source/winbindd/winbindd_idmap.c
+++ b/source/winbindd/winbindd_idmap.c
@@ -170,6 +170,108 @@ enum winbindd_result winbindd_dual_set_hwm(struct winbindd_domain *domain,
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
+static void winbindd_sids2xids_recv(TALLOC_CTX *mem_ctx, bool success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, bool succ, void *, int) =
+ (void (*)(void *, bool, void *, int))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger sids2xids\n"));
+ cont(private_data, False, NULL, 0);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("sids2xids returned an error\n"));
+ cont(private_data, False, NULL, 0);
+ return;
+ }
+
+ cont(private_data, True, response->extra_data.data, response->length - sizeof(response));
+}
+
+void winbindd_sids2xids_async(TALLOC_CTX *mem_ctx, void *sids, int size,
+ void (*cont)(void *private_data, bool success, void *data, int len),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_SIDS2XIDS;
+ request.extra_data.data = (char *)sids;
+ request.extra_len = size;
+ do_async(mem_ctx, idmap_child(), &request, winbindd_sids2xids_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_sids2xids(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ DOM_SID *sids;
+ struct unixid *xids;
+ struct id_map **ids;
+ NTSTATUS result;
+ int num, i;
+
+ DEBUG(3, ("[%5lu]: sids to unix ids\n", (unsigned long)state->pid));
+
+ if (state->request.extra_len == 0) {
+ DEBUG(0, ("Invalid buffer size!\n"));
+ return WINBINDD_ERROR;
+ }
+
+ sids = (DOM_SID *)state->request.extra_data.data;
+ num = state->request.extra_len / sizeof(DOM_SID);
+
+ ids = TALLOC_ZERO_ARRAY(state->mem_ctx, struct id_map *, num + 1);
+ if ( ! ids) {
+ DEBUG(0, ("Out of memory!\n"));
+ return WINBINDD_ERROR;
+ }
+ for (i = 0; i < num; i++) {
+ ids[i] = TALLOC_P(ids, struct id_map);
+ if ( ! ids[i]) {
+ DEBUG(0, ("Out of memory!\n"));
+ talloc_free(ids);
+ return WINBINDD_ERROR;
+ }
+ ids[i]->sid = &sids[i];
+ }
+
+ result = idmap_sids_to_unixids(ids);
+
+ if (NT_STATUS_IS_OK(result)) {
+
+ xids = SMB_MALLOC_ARRAY(struct unixid, num);
+ if ( ! xids) {
+ DEBUG(0, ("Out of memory!\n"));
+ talloc_free(ids);
+ return WINBINDD_ERROR;
+ }
+
+ for (i = 0; i < num; i++) {
+ if (ids[i]->status == ID_MAPPED) {
+ xids[i].type = ids[i]->xid.type;
+ xids[i].id = ids[i]->xid.id;
+ } else {
+ xids[i].type = -1;
+ }
+ }
+
+ state->response.length = sizeof(state->response) + (sizeof(struct unixid) * num);
+ state->response.extra_data.data = xids;
+
+ } else {
+ DEBUG (2, ("idmap_sids_to_unixids returned an error: 0x%08x\n", NT_STATUS_V(result)));
+ talloc_free(ids);
+ return WINBINDD_ERROR;
+ }
+
+ talloc_free(ids);
+ return WINBINDD_OK;
+}
+
static void winbindd_sid2uid_recv(TALLOC_CTX *mem_ctx, bool success,
struct winbindd_response *response,
void *c, void *private_data)
@@ -197,28 +299,8 @@ void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
void *private_data)
{
struct winbindd_request request;
- struct winbindd_domain *domain;
-
ZERO_STRUCT(request);
request.cmd = WINBINDD_DUAL_SID2UID;
-
- domain = find_domain_from_sid(sid);
-
- if (domain != NULL) {
- DEBUG(10, ("winbindd_sid2uid_async found domain %s, "
- "have_idmap_config = %d\n", domain->name,
- (int)domain->have_idmap_config));
-
- }
- else {
- DEBUG(10, ("winbindd_sid2uid_async did not find a domain for "
- "%s\n", sid_string_dbg(sid)));
- }
-
- if ((domain != NULL) && (domain->have_idmap_config)) {
- fstrcpy(request.domain_name, domain->name);
- }
-
sid_to_fstring(request.data.dual_sid2id.sid, sid);
do_async(mem_ctx, idmap_child(), &request, winbindd_sid2uid_recv,
(void *)cont, private_data);
@@ -239,12 +321,9 @@ enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain,
return WINBINDD_ERROR;
}
- result = idmap_sid_to_uid(state->request.domain_name, &sid,
- &state->response.data.uid);
+ /* Find uid for this sid and return it, possibly ask the slow remote idmap */
- DEBUG(10, ("winbindd_dual_sid2uid: 0x%08x - %s - %u\n",
- NT_STATUS_V(result), sid_string_dbg(&sid),
- state->response.data.uid));
+ result = idmap_sid_to_uid(&sid, &(state->response.data.uid));
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
@@ -276,16 +355,8 @@ void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
void *private_data)
{
struct winbindd_request request;
- struct winbindd_domain *domain;
-
ZERO_STRUCT(request);
request.cmd = WINBINDD_DUAL_SID2GID;
-
- domain = find_domain_from_sid(sid);
- if ((domain != NULL) && (domain->have_idmap_config)) {
- fstrcpy(request.domain_name, domain->name);
- }
-
sid_to_fstring(request.data.dual_sid2id.sid, sid);
DEBUG(7,("winbindd_sid2gid_async: Resolving %s to a gid\n",
@@ -312,8 +383,7 @@ enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain,
/* Find gid for this sid and return it, possibly ask the slow remote idmap */
- result = idmap_sid_to_gid(state->request.domain_name, &sid,
- &state->response.data.gid);
+ result = idmap_sid_to_gid(&sid, &state->response.data.gid);
DEBUG(10, ("winbindd_dual_sid2gid: 0x%08x - %s - %u\n",
NT_STATUS_V(result), sid_string_dbg(&sid),
@@ -351,21 +421,11 @@ void winbindd_uid2sid_async(TALLOC_CTX *mem_ctx, uid_t uid,
void (*cont)(void *private_data, bool success, const char *sid),
void *private_data)
{
- struct winbindd_domain *domain;
struct winbindd_request request;
ZERO_STRUCT(request);
request.cmd = WINBINDD_DUAL_UID2SID;
request.data.uid = uid;
-
- for (domain = domain_list(); domain != NULL; domain = domain->next) {
- if (domain->have_idmap_config
- && (uid >= domain->id_range_low)
- && (uid <= domain->id_range_high)) {
- fstrcpy(request.domain_name, domain->name);
- }
- }
-
do_async(mem_ctx, idmap_child(), &request, winbindd_uid2sid_recv,
(void *)cont, private_data);
}
@@ -381,8 +441,7 @@ enum winbindd_result winbindd_dual_uid2sid(struct winbindd_domain *domain,
(unsigned long) state->request.data.uid));
/* Find sid for this uid and return it, possibly ask the slow remote idmap */
- result = idmap_uid_to_sid(state->request.domain_name, &sid,
- state->request.data.uid);
+ result = idmap_uid_to_sid(&sid, state->request.data.uid);
if (NT_STATUS_IS_OK(result)) {
sid_to_fstring(state->response.data.sid.sid, &sid);
@@ -419,21 +478,11 @@ void winbindd_gid2sid_async(TALLOC_CTX *mem_ctx, gid_t gid,
void (*cont)(void *private_data, bool success, const char *sid),
void *private_data)
{
- struct winbindd_domain *domain;
struct winbindd_request request;
ZERO_STRUCT(request);
request.cmd = WINBINDD_DUAL_GID2SID;
request.data.gid = gid;
-
- for (domain = domain_list(); domain != NULL; domain = domain->next) {
- if (domain->have_idmap_config
- && (gid >= domain->id_range_low)
- && (gid <= domain->id_range_high)) {
- fstrcpy(request.domain_name, domain->name);
- }
- }
-
do_async(mem_ctx, idmap_child(), &request, winbindd_gid2sid_recv,
(void *)cont, private_data);
}
@@ -449,8 +498,7 @@ enum winbindd_result winbindd_dual_gid2sid(struct winbindd_domain *domain,
(unsigned long) state->request.data.gid));
/* Find sid for this gid and return it, possibly ask the slow remote idmap */
- result = idmap_gid_to_sid(state->request.domain_name, &sid,
- state->request.data.gid);
+ result = idmap_gid_to_sid(&sid, state->request.data.gid);
if (NT_STATUS_IS_OK(result)) {
sid_to_fstring(state->response.data.sid.sid, &sid);
@@ -473,6 +521,12 @@ static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = {
.name = "DUAL_SID2GID",
.struct_cmd = WINBINDD_DUAL_SID2GID,
.struct_fn = winbindd_dual_sid2gid,
+#if 0 /* DISABLED until we fix the interface in Samba 3.0.26 --jerry */
+ },{
+ .name = "DUAL_SIDS2XIDS",
+ .struct_cmd = WINBINDD_DUAL_SIDS2XIDS,
+ .struct_fn = winbindd_dual_sids2xids,
+#endif /* end DISABLED */
},{
.name = "DUAL_UID2SID",
.struct_cmd = WINBINDD_DUAL_UID2SID,
diff --git a/source/winbindd/winbindd_locator.c b/source/winbindd/winbindd_locator.c
index b2a8bd7e30..709fbcc5d1 100644
--- a/source/winbindd/winbindd_locator.c
+++ b/source/winbindd/winbindd_locator.c
@@ -54,54 +54,12 @@ void winbindd_dsgetdcname(struct winbindd_cli_state *state)
sendto_child(state, locator_child());
}
-struct wbc_flag_map {
- uint32_t wbc_dc_flag;
- uint32_t ds_dc_flags;
-};
-
-static uint32_t get_dsgetdc_flags(uint32_t wbc_flags)
-{
- struct wbc_flag_map lookup_dc_flags[] = {
- { WBC_LOOKUP_DC_FORCE_REDISCOVERY, DS_FORCE_REDISCOVERY },
- { WBC_LOOKUP_DC_DS_REQUIRED, DS_DIRECTORY_SERVICE_REQUIRED },
- { WBC_LOOKUP_DC_DS_PREFERRED, DS_DIRECTORY_SERVICE_PREFERRED},
- { WBC_LOOKUP_DC_GC_SERVER_REQUIRED, DS_GC_SERVER_REQUIRED },
- { WBC_LOOKUP_DC_PDC_REQUIRED, DS_PDC_REQUIRED},
- { WBC_LOOKUP_DC_BACKGROUND_ONLY, DS_BACKGROUND_ONLY },
- { WBC_LOOKUP_DC_IP_REQUIRED, DS_IP_REQUIRED },
- { WBC_LOOKUP_DC_KDC_REQUIRED, DS_KDC_REQUIRED },
- { WBC_LOOKUP_DC_TIMESERV_REQUIRED, DS_TIMESERV_REQUIRED },
- { WBC_LOOKUP_DC_WRITABLE_REQUIRED, DS_WRITABLE_REQUIRED },
- { WBC_LOOKUP_DC_GOOD_TIMESERV_PREFERRED, DS_GOOD_TIMESERV_PREFERRED },
- { WBC_LOOKUP_DC_AVOID_SELF, DS_AVOID_SELF },
- { WBC_LOOKUP_DC_ONLY_LDAP_NEEDED, DS_ONLY_LDAP_NEEDED },
- { WBC_LOOKUP_DC_IS_FLAT_NAME, DS_IS_FLAT_NAME },
- { WBC_LOOKUP_DC_IS_DNS_NAME, DS_IS_DNS_NAME },
- { WBC_LOOKUP_DC_TRY_NEXTCLOSEST_SITE, DS_TRY_NEXTCLOSEST_SITE },
- { WBC_LOOKUP_DC_DS_6_REQUIRED, DS_DIRECTORY_SERVICE_6_REQUIRED },
- { WBC_LOOKUP_DC_RETURN_DNS_NAME, DS_RETURN_DNS_NAME },
- { WBC_LOOKUP_DC_RETURN_FLAT_NAME, DS_RETURN_FLAT_NAME }
- };
- uint32_t ds_flags = 0;
- int i = 0 ;
- int num_entries = sizeof(lookup_dc_flags) / sizeof(struct wbc_flag_map);
-
- for (i=0; i<num_entries; i++) {
- if (wbc_flags & lookup_dc_flags[i].wbc_dc_flag)
- ds_flags |= lookup_dc_flags[i].ds_dc_flags;
- }
-
- return ds_flags;
-}
-
-
static enum winbindd_result dual_dsgetdcname(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
NTSTATUS result;
struct netr_DsRGetDCNameInfo *info = NULL;
const char *dc = NULL;
- uint32_t ds_flags = 0;
state->request.domain_name
[sizeof(state->request.domain_name)-1] = '\0';
@@ -109,11 +67,9 @@ static enum winbindd_result dual_dsgetdcname(struct winbindd_domain *domain,
DEBUG(3, ("[%5lu]: dsgetdcname for %s\n", (unsigned long)state->pid,
state->request.domain_name));
- ds_flags = get_dsgetdc_flags(state->request.flags);
-
result = dsgetdcname(state->mem_ctx, winbind_messaging_context(),
state->request.domain_name,
- NULL, NULL, ds_flags, &info);
+ NULL, NULL, state->request.flags, &info);
if (!NT_STATUS_IS_OK(result)) {
return WINBINDD_ERROR;
diff --git a/source/winbindd/winbindd_misc.c b/source/winbindd/winbindd_misc.c
index 50936c01a3..ddfaa7d7ae 100644
--- a/source/winbindd/winbindd_misc.c
+++ b/source/winbindd/winbindd_misc.c
@@ -86,7 +86,10 @@ enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *do
"good" : "bad"));
done:
- set_auth_errors(&state->response, result);
+ state->response.data.auth.nt_status = NT_STATUS_V(result);
+ fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
+ fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
+ state->response.data.auth.pam_error = nt_status_to_pam(result);
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Checking the trust account password returned %s\n",
state->response.data.auth.nt_status_string));
@@ -463,7 +466,7 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
/* This call can take a long time - allow the server to time out.
35 seconds should do it. */
- orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
+ orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);
req_domain = find_domain_from_name_noinit(state->request.domain_name);
if (req_domain == domain) {
@@ -482,7 +485,7 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
&werr);
}
/* And restore our original timeout. */
- rpccli_set_timeout(netlogon_pipe, orig_timeout);
+ cli_set_timeout(netlogon_pipe->cli, orig_timeout);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(5,("Error requesting DCname for domain %s: %s\n",
diff --git a/source/winbindd/winbindd_pam.c b/source/winbindd/winbindd_pam.c
index d9104ca600..90849b59c3 100644
--- a/source/winbindd/winbindd_pam.c
+++ b/source/winbindd/winbindd_pam.c
@@ -176,7 +176,7 @@ static NTSTATUS append_unix_username(TALLOC_CTX *mem_ctx,
}
fill_domain_username(state->response.data.auth.unix_username,
- nt_domain, nt_username, true);
+ nt_domain, nt_username, True);
DEBUG(5,("Setting unix username to [%s]\n",
state->response.data.auth.unix_username));
@@ -310,8 +310,8 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
TALLOC_FREE(frame);
- status = sid_array_from_info3(mem_ctx, info3,
- &token->user_sids,
+ status = sid_array_from_info3(mem_ctx, info3,
+ &token->user_sids,
&token->num_sids,
true, false);
if (!NT_STATUS_IS_OK(status)) {
@@ -338,13 +338,13 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
}
-
+
/* Do not distinguish this error from a wrong username/pw */
return NT_STATUS_LOGON_FAILURE;
}
-struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state,
+struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state,
const char *domain_name)
{
struct winbindd_domain *domain;
@@ -353,7 +353,7 @@ struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state,
domain = find_domain_from_name_noinit(domain_name);
if (domain == NULL) {
DEBUG(3, ("Authentication for domain [%s] refused "
- "as it is not a trusted domain\n",
+ "as it is not a trusted domain\n",
domain_name));
}
return domain;
@@ -370,30 +370,27 @@ struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state,
if (state->request.flags & WBFLAG_PAM_CONTACT_TRUSTDOM) {
domain = find_domain_from_name_noinit(domain_name);
if (domain == NULL) {
- DEBUG(3, ("Authentication for domain [%s] skipped "
- "as it is not a trusted domain\n",
+ DEBUG(3, ("Authentication for domain [%s] skipped "
+ "as it is not a trusted domain\n",
domain_name));
} else {
return domain;
- }
+ }
}
return find_our_domain();
}
-static void fill_in_password_policy(struct winbindd_response *r,
- const struct samr_DomInfo1 *p)
+static void set_auth_errors(struct winbindd_response *resp, NTSTATUS result)
{
- r->data.auth.policy.min_length_password =
- p->min_password_length;
- r->data.auth.policy.password_history =
- p->password_history_length;
- r->data.auth.policy.password_properties =
- p->password_properties;
- r->data.auth.policy.expire =
- nt_time_to_unix_abs((NTTIME *)&(p->max_password_age));
- r->data.auth.policy.min_passwordage =
- nt_time_to_unix_abs((NTTIME *)&(p->min_password_age));
+ resp->data.auth.nt_status = NT_STATUS_V(result);
+ fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result));
+
+ /* we might have given a more useful error above */
+ if (*resp->data.auth.error_string == '\0')
+ fstrcpy(resp->data.auth.error_string,
+ get_friendly_nt_error_msg(result));
+ resp->data.auth.pam_error = nt_status_to_pam(result);
}
static NTSTATUS fillup_password_policy(struct winbindd_domain *domain,
@@ -405,9 +402,9 @@ static NTSTATUS fillup_password_policy(struct winbindd_domain *domain,
if ( !winbindd_can_contact_domain( domain ) ) {
DEBUG(5,("fillup_password_policy: No inbound trust to "
- "contact domain %s\n", domain->name));
+ "contact domain %s\n", domain->name));
return NT_STATUS_NOT_SUPPORTED;
- }
+ }
methods = domain->methods;
@@ -416,13 +413,22 @@ static NTSTATUS fillup_password_policy(struct winbindd_domain *domain,
return status;
}
- fill_in_password_policy(&state->response, &password_policy);
+ state->response.data.auth.policy.min_length_password =
+ password_policy.min_password_length;
+ state->response.data.auth.policy.password_history =
+ password_policy.password_history_length;
+ state->response.data.auth.policy.password_properties =
+ password_policy.password_properties;
+ state->response.data.auth.policy.expire =
+ nt_time_to_unix_abs((NTTIME *)&(password_policy.max_password_age));
+ state->response.data.auth.policy.min_passwordage =
+ nt_time_to_unix_abs((NTTIME *)&(password_policy.min_password_age));
return NT_STATUS_OK;
}
-static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
+static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
uint16 *lockout_threshold)
{
struct winbindd_methods *methods;
@@ -443,8 +449,8 @@ static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain
return NT_STATUS_OK;
}
-static NTSTATUS get_pwd_properties(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
+static NTSTATUS get_pwd_properties(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
uint32 *password_properties)
{
struct winbindd_methods *methods;
@@ -467,7 +473,7 @@ static NTSTATUS get_pwd_properties(struct winbindd_domain *domain,
#ifdef HAVE_KRB5
-static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx,
+static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx,
const char *type,
uid_t uid,
bool *internal_ccache)
@@ -478,7 +484,7 @@ static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx,
const char *gen_cc = NULL;
- *internal_ccache = true;
+ *internal_ccache = True;
if (uid == -1) {
goto memory_ccache;
@@ -497,7 +503,7 @@ static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx,
goto memory_ccache;
}
- *internal_ccache = false;
+ *internal_ccache = False;
goto done;
memory_ccache:
@@ -526,11 +532,11 @@ static void setup_return_cc_name(struct winbindd_cli_state *state, const char *c
if (!strequal(type, "FILE") &&
!strequal(type, "WRFILE")) {
- DEBUG(10,("won't return krbccname for a %s type ccache\n",
+ DEBUG(10,("won't return krbccname for a %s type ccache\n",
type));
return;
}
-
+
fstrcpy(state->response.data.auth.krb5ccname, cc);
}
@@ -571,13 +577,13 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain,
uid_t uid = -1;
ADS_STRUCT *ads;
time_t time_offset = 0;
- bool internal_ccache = true;
+ bool internal_ccache = True;
ZERO_STRUCTP(info3);
*info3 = NULL;
-
- /* 1st step:
+
+ /* 1st step:
* prepare a krb5_cc_cache string for the user */
uid = get_uid_from_state(state);
@@ -587,31 +593,31 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain,
cc = generate_krb5_ccache(state->mem_ctx,
state->request.data.auth.krb5_cc_type,
- state->request.data.auth.uid,
+ state->request.data.auth.uid,
&internal_ccache);
if (cc == NULL) {
return NT_STATUS_NO_MEMORY;
}
- /* 2nd step:
+ /* 2nd step:
* get kerberos properties */
-
+
if (domain->private_data) {
ads = (ADS_STRUCT *)domain->private_data;
- time_offset = ads->auth.time_offset;
+ time_offset = ads->auth.time_offset;
}
- /* 3rd step:
+ /* 3rd step:
* do kerberos auth and setup ccache as the user */
parse_domain_user(state->request.data.auth.user, name_domain, name_user);
realm = domain->alt_name;
strupper_m(realm);
-
- principal_s = talloc_asprintf(state->mem_ctx, "%s@%s", name_user, realm);
+
+ principal_s = talloc_asprintf(state->mem_ctx, "%s@%s", name_user, realm);
if (principal_s == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -638,8 +644,8 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain,
&ticket_lifetime,
&renewal_until,
cc,
- true,
- true,
+ True,
+ True,
WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
info3);
if (!internal_ccache) {
@@ -659,7 +665,7 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain,
* environment */
if (!internal_ccache) {
-
+
setup_return_cc_name(state, cc);
result = add_ccache_to_list(principal_s,
@@ -670,11 +676,11 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain,
uid,
time(NULL),
ticket_lifetime,
- renewal_until,
- false);
+ renewal_until,
+ False);
if (!NT_STATUS_IS_OK(result)) {
- DEBUG(10,("winbindd_raw_kerberos_login: failed to add ccache to list: %s\n",
+ DEBUG(10,("winbindd_raw_kerberos_login: failed to add ccache to list: %s\n",
nt_errstr(result)));
}
} else {
@@ -731,12 +737,12 @@ static bool check_request_flags(uint32_t flags)
( (flags & flags_edata) == WBFLAG_PAM_INFO3_NDR) ||
( (flags & flags_edata) == WBFLAG_PAM_INFO3_TEXT)||
!(flags & flags_edata) ) {
- return true;
+ return True;
}
DEBUG(1,("check_request_flags: invalid request flags[0x%08X]\n",flags));
- return false;
+ return False;
}
/****************************************************************
@@ -811,9 +817,7 @@ void winbindd_pam_auth(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
fstring name_domain, name_user;
- char *mapped_user = NULL;
NTSTATUS result;
- NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
/* Ensure null termination */
state->request.data.auth.user
@@ -832,21 +836,11 @@ void winbindd_pam_auth(struct winbindd_cli_state *state)
}
/* Parse domain and username */
+
+ ws_name_return( state->request.data.auth.user, WB_REPLACE_CHAR );
- name_map_status = normalize_name_unmap(state->mem_ctx,
- state->request.data.auth.user,
- &mapped_user);
-
- /* If the name normalization didnt' actually do anything,
- just use the original name */
-
- if (!NT_STATUS_IS_OK(name_map_status) &&
- !NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
- {
- mapped_user = state->request.data.auth.user;
- }
-
- if (!canonicalize_username(mapped_user, name_domain, name_user)) {
+ if (!canonicalize_username(state->request.data.auth.user,
+ name_domain, name_user)) {
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
@@ -875,7 +869,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
struct netr_SamInfo3 **info3)
{
NTSTATUS result = NT_STATUS_LOGON_FAILURE;
- uint16 max_allowed_bad_attempts;
+ uint16 max_allowed_bad_attempts;
fstring name_domain, name_user;
DOM_SID sid;
enum lsa_SidType type;
@@ -884,7 +878,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
const uint8 *cached_salt;
struct netr_SamInfo3 *my_info3;
time_t kickoff_time, must_change_time;
- bool password_good = false;
+ bool password_good = False;
#ifdef HAVE_KRB5
struct winbindd_tdc_domain *tdc_domain = NULL;
#endif
@@ -896,7 +890,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
DEBUG(10,("winbindd_dual_pam_auth_cached\n"));
/* Parse domain and username */
-
+
parse_domain_user(state->request.data.auth.user, name_domain, name_user);
@@ -914,10 +908,10 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
return NT_STATUS_LOGON_FAILURE;
}
- result = winbindd_get_creds(domain,
- state->mem_ctx,
- &sid,
- &my_info3,
+ result = winbindd_get_creds(domain,
+ state->mem_ctx,
+ &sid,
+ &my_info3,
&cached_nt_pass,
&cached_salt);
if (!NT_STATUS_IS_OK(result)) {
@@ -942,42 +936,42 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
E_md5hash(cached_salt, new_nt_pass, salted_hash);
password_good = (memcmp(cached_nt_pass, salted_hash, NT_HASH_LEN) == 0) ?
- true : false;
+ True : False;
} else {
/* Old cached cred - direct store of nt_hash (bad bad bad !). */
password_good = (memcmp(cached_nt_pass, new_nt_pass, NT_HASH_LEN) == 0) ?
- true : false;
+ True : False;
}
if (password_good) {
/* User *DOES* know the password, update logon_time and reset
* bad_pw_count */
-
+
my_info3->base.user_flags |= NETLOGON_CACHED_ACCOUNT;
-
+
if (my_info3->base.acct_flags & ACB_AUTOLOCK) {
return NT_STATUS_ACCOUNT_LOCKED_OUT;
}
-
+
if (my_info3->base.acct_flags & ACB_DISABLED) {
return NT_STATUS_ACCOUNT_DISABLED;
}
-
+
if (my_info3->base.acct_flags & ACB_WSTRUST) {
return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
}
-
+
if (my_info3->base.acct_flags & ACB_SVRTRUST) {
return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT;
}
-
+
if (my_info3->base.acct_flags & ACB_DOMTRUST) {
return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;
}
if (!(my_info3->base.acct_flags & ACB_NORMAL)) {
- DEBUG(0,("winbindd_dual_pam_auth_cached: whats wrong with that one?: 0x%08x\n",
+ DEBUG(0,("winbindd_dual_pam_auth_cached: whats wrong with that one?: 0x%08x\n",
my_info3->base.acct_flags));
return NT_STATUS_LOGON_FAILURE;
}
@@ -994,7 +988,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
/* return NT_STATUS_PASSWORD_EXPIRED; */
goto success;
}
-
+
#ifdef HAVE_KRB5
if ((state->request.flags & WBFLAG_PAM_KRB5) &&
((tdc_domain = wcache_tdc_fetch_domain(state->mem_ctx, name_domain)) != NULL) &&
@@ -1005,7 +999,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
char *realm = NULL;
const char *principal_s = NULL;
const char *service = NULL;
- bool internal_ccache = false;
+ bool internal_ccache = False;
uid = get_uid_from_state(state);
if (uid == -1) {
@@ -1047,7 +1041,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
time(NULL),
time(NULL) + lp_winbind_cache_time(),
time(NULL) + WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
- true);
+ True);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(10,("winbindd_dual_pam_auth_cached: failed "
@@ -1119,7 +1113,7 @@ failed:
my_info3);
if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0,("winbindd_dual_pam_auth_cached: failed to update creds %s\n",
+ DEBUG(0,("winbindd_dual_pam_auth_cached: failed to update creds %s\n",
nt_errstr(result)));
}
@@ -1127,7 +1121,7 @@ failed:
}
NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain,
- struct winbindd_cli_state *state,
+ struct winbindd_cli_state *state,
struct netr_SamInfo3 **info3)
{
struct winbindd_domain *contact_domain;
@@ -1135,38 +1129,38 @@ NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain,
NTSTATUS result;
DEBUG(10,("winbindd_dual_pam_auth_kerberos\n"));
-
+
/* Parse domain and username */
-
+
parse_domain_user(state->request.data.auth.user, name_domain, name_user);
/* what domain should we contact? */
-
+
if ( IS_DC ) {
if (!(contact_domain = find_domain_from_name(name_domain))) {
- DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
- state->request.data.auth.user, name_domain, name_user, name_domain));
+ DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
+ state->request.data.auth.user, name_domain, name_user, name_domain));
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
-
+
} else {
if (is_myname(name_domain)) {
DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
-
+
contact_domain = find_domain_from_name(name_domain);
if (contact_domain == NULL) {
- DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
- state->request.data.auth.user, name_domain, name_user, name_domain));
+ DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
+ state->request.data.auth.user, name_domain, name_user, name_domain));
contact_domain = find_our_domain();
}
}
- if (contact_domain->initialized &&
+ if (contact_domain->initialized &&
contact_domain->active_directory) {
goto try_login;
}
@@ -1185,18 +1179,6 @@ done:
return result;
}
-typedef NTSTATUS (*netlogon_fn_t)(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx,
- uint32 logon_parameters,
- const char *server,
- const char *username,
- const char *domain,
- const char *workstation,
- const uint8 chal[8],
- DATA_BLOB lm_response,
- DATA_BLOB nt_response,
- struct netr_SamInfo3 **info3);
-
NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
struct winbindd_cli_state *state,
struct netr_SamInfo3 **info3)
@@ -1218,13 +1200,13 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
*info3 = NULL;
DEBUG(10,("winbindd_dual_pam_auth_samlogon\n"));
-
+
/* Parse domain and username */
-
+
parse_domain_user(state->request.data.auth.user, name_domain, name_user);
/* do password magic */
-
+
generate_random_buffer(chal, 8);
if (lp_client_ntlmv2_auth()) {
@@ -1232,17 +1214,17 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
DATA_BLOB names_blob;
DATA_BLOB nt_response;
DATA_BLOB lm_response;
- server_chal = data_blob_talloc(state->mem_ctx, chal, 8);
-
+ server_chal = data_blob_talloc(state->mem_ctx, chal, 8);
+
/* note that the 'workgroup' here is a best guess - we don't know
the server's domain at this point. The 'server name' is also
- dodgy...
+ dodgy...
*/
names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup());
-
- if (!SMBNTLMv2encrypt(name_user, name_domain,
- state->request.data.auth.pass,
- &server_chal,
+
+ if (!SMBNTLMv2encrypt(name_user, name_domain,
+ state->request.data.auth.pass,
+ &server_chal,
&names_blob,
&lm_response, &nt_response, NULL)) {
data_blob_free(&names_blob);
@@ -1261,35 +1243,35 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
data_blob_free(&nt_response);
} else {
- if (lp_client_lanman_auth()
- && SMBencrypt(state->request.data.auth.pass,
- chal,
+ if (lp_client_lanman_auth()
+ && SMBencrypt(state->request.data.auth.pass,
+ chal,
local_lm_response)) {
- lm_resp = data_blob_talloc(state->mem_ctx,
- local_lm_response,
+ lm_resp = data_blob_talloc(state->mem_ctx,
+ local_lm_response,
sizeof(local_lm_response));
} else {
lm_resp = data_blob_null;
}
- SMBNTencrypt(state->request.data.auth.pass,
+ SMBNTencrypt(state->request.data.auth.pass,
chal,
local_nt_response);
- nt_resp = data_blob_talloc(state->mem_ctx,
- local_nt_response,
+ nt_resp = data_blob_talloc(state->mem_ctx,
+ local_nt_response,
sizeof(local_nt_response));
}
-
+
/* what domain should we contact? */
-
+
if ( IS_DC ) {
if (!(contact_domain = find_domain_from_name(name_domain))) {
- DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
- state->request.data.auth.user, name_domain, name_user, name_domain));
+ DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
+ state->request.data.auth.user, name_domain, name_user, name_domain));
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
-
+
} else {
if (is_myname(name_domain)) {
DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));
@@ -1303,10 +1285,20 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
/* check authentication loop */
do {
- netlogon_fn_t logon_fn;
+ NTSTATUS (*logon_fn)(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 logon_parameters,
+ const char *server,
+ const char *username,
+ const char *domain,
+ const char *workstation,
+ const uint8 chal[8],
+ DATA_BLOB lm_response,
+ DATA_BLOB nt_response,
+ struct netr_SamInfo3 **info3);
ZERO_STRUCTP(my_info3);
- retry = false;
+ retry = False;
result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
@@ -1318,7 +1310,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
/* It is really important to try SamLogonEx here,
* because in a clustered environment, we want to use
* one machine account from multiple physical
- * computers.
+ * computers.
*
* With a normal SamLogon call, we must keep the
* credentials chain updated and intact between all
@@ -1332,7 +1324,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
* When using SamLogonEx, the credentials are not
* supplied, but the session key is implied by the
* wrapping SamLogon context.
- *
+ *
* -- abartlet 21 April 2008
*/
@@ -1357,8 +1349,8 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
&& contact_domain->can_do_samlogon_ex) {
DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
"retrying with NetSamLogon\n"));
- contact_domain->can_do_samlogon_ex = false;
- retry = true;
+ contact_domain->can_do_samlogon_ex = False;
+ retry = True;
continue;
}
@@ -1367,15 +1359,15 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
our connection. */
if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) {
- retry = true;
+ retry = True;
continue;
}
-
+
/* if we get access denied, a possible cause was that we had
and open connection to the DC, but someone changed our
machine account password out from underneath us using 'net
rpc changetrustpw' */
-
+
if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) ) {
DEBUG(3,("winbindd_pam_auth: sam_logon returned "
"ACCESS_DENIED. Maybe the trust account "
@@ -1383,16 +1375,16 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
"Killing connections to domain %s\n",
name_domain));
invalidate_cm_connection(&contact_domain->conn);
- retry = true;
- }
-
+ retry = True;
+ }
+
} while ( (attempts < 2) && retry );
/* handle the case where a NT4 DC does not fill in the acct_flags in
* the samlogon reply info3. When accurate info3 is required by the
* caller, we look up the account flags ourselve - gd */
- if ((state->request.flags & WBFLAG_PAM_INFO3_TEXT) &&
+ if ((state->request.flags & WBFLAG_PAM_INFO3_TEXT) &&
NT_STATUS_IS_OK(result) && (my_info3->base.acct_flags == 0)) {
struct rpc_pipe_client *samr_pipe;
@@ -1401,11 +1393,11 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
NTSTATUS status_tmp;
uint32 acct_flags;
- status_tmp = cm_connect_sam(contact_domain, state->mem_ctx,
+ status_tmp = cm_connect_sam(contact_domain, state->mem_ctx,
&samr_pipe, &samr_domain_handle);
if (!NT_STATUS_IS_OK(status_tmp)) {
- DEBUG(3, ("could not open handle to SAMR pipe: %s\n",
+ DEBUG(3, ("could not open handle to SAMR pipe: %s\n",
nt_errstr(status_tmp)));
goto done;
}
@@ -1454,15 +1446,12 @@ done:
}
enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
+ struct winbindd_cli_state *state)
{
NTSTATUS result = NT_STATUS_LOGON_FAILURE;
- NTSTATUS krb5_result = NT_STATUS_OK;
+ NTSTATUS krb5_result = NT_STATUS_OK;
fstring name_domain, name_user;
- char *mapped_user;
- fstring domain_user;
struct netr_SamInfo3 *info3 = NULL;
- NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
/* Ensure null termination */
state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
@@ -1479,29 +1468,12 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
}
/* Parse domain and username */
+
+ ws_name_return( state->request.data.auth.user, WB_REPLACE_CHAR );
- name_map_status = normalize_name_unmap(state->mem_ctx,
- state->request.data.auth.user,
- &mapped_user);
-
- /* If the name normalization didnt' actually do anything,
- just use the original name */
-
- if (!NT_STATUS_IS_OK(name_map_status) &&
- !NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
- {
- mapped_user = state->request.data.auth.user;
- }
-
- parse_domain_user(mapped_user, name_domain, name_user);
-
- if ( mapped_user != state->request.data.auth.user ) {
- fstr_sprintf( domain_user, "%s\\%s", name_domain, name_user );
- safe_strcpy( state->request.data.auth.user, domain_user,
- sizeof(state->request.data.auth.user)-1 );
- }
+ parse_domain_user(state->request.data.auth.user, name_domain, name_user);
- if (domain->online == false) {
+ if (domain->online == False) {
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
if (domain->startup) {
/* Logons are very important to users. If we're offline and
@@ -1520,11 +1492,11 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
/* Check for Kerberos authentication */
if (domain->online && (state->request.flags & WBFLAG_PAM_KRB5)) {
-
+
result = winbindd_dual_pam_auth_kerberos(domain, state, &info3);
/* save for later */
krb5_result = result;
-
+
if (NT_STATUS_IS_OK(result)) {
DEBUG(10,("winbindd_dual_pam_auth_kerberos succeeded\n"));
@@ -1538,7 +1510,7 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
DEBUG(10,("winbindd_dual_pam_auth_kerberos setting domain to offline\n"));
set_domain_offline( domain );
- goto cached_logon;
+ goto cached_logon;
}
/* there are quite some NT_STATUS errors where there is no
@@ -1557,7 +1529,7 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
NT_STATUS_EQUAL(result, NT_STATUS_WRONG_PASSWORD)) {
goto process_result;
}
-
+
if (state->request.flags & WBFLAG_PAM_FALLBACK_AFTER_KRB5) {
DEBUG(3,("falling back to samlogon\n"));
goto sam_logon;
@@ -1570,7 +1542,7 @@ sam_logon:
/* Check for Samlogon authentication */
if (domain->online) {
result = winbindd_dual_pam_auth_samlogon(domain, state, &info3);
-
+
if (NT_STATUS_IS_OK(result)) {
DEBUG(10,("winbindd_dual_pam_auth_samlogon succeeded\n"));
/* add the Krb5 err if we have one */
@@ -1578,18 +1550,18 @@ sam_logon:
info3->base.user_flags |= LOGON_KRB5_FAIL_CLOCK_SKEW;
}
goto process_result;
- }
+ }
- DEBUG(10,("winbindd_dual_pam_auth_samlogon failed: %s\n",
+ DEBUG(10,("winbindd_dual_pam_auth_samlogon failed: %s\n",
nt_errstr(result)));
if (NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS) ||
NT_STATUS_EQUAL(result, NT_STATUS_IO_TIMEOUT) ||
- NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND))
+ NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND))
{
DEBUG(10,("winbindd_dual_pam_auth_samlogon setting domain to offline\n"));
set_domain_offline( domain );
- goto cached_logon;
+ goto cached_logon;
}
if (domain->online) {
@@ -1600,9 +1572,9 @@ sam_logon:
cached_logon:
/* Check for Cached logons */
- if (!domain->online && (state->request.flags & WBFLAG_PAM_CACHED_LOGIN) &&
+ if (!domain->online && (state->request.flags & WBFLAG_PAM_CACHED_LOGIN) &&
lp_winbind_offline_logon()) {
-
+
result = winbindd_dual_pam_auth_cached(domain, state, &info3);
if (NT_STATUS_IS_OK(result)) {
@@ -1617,7 +1589,7 @@ cached_logon:
process_result:
if (NT_STATUS_IS_OK(result)) {
-
+
DOM_SID user_sid;
/* In all codepaths where result == NT_STATUS_OK info3 must have
@@ -1634,19 +1606,19 @@ process_result:
this is our primary domain so we don't invalidate
the cache entry by storing the seq_num for the wrong
domain). */
- if ( domain->primary ) {
+ if ( domain->primary ) {
sid_compose(&user_sid, info3->base.domain_sid,
info3->base.rid);
- cache_name2sid(domain, name_domain, name_user,
+ cache_name2sid(domain, name_domain, name_user,
SID_NAME_USER, &user_sid);
}
-
+
/* Check if the user is in the right group */
if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, info3,
state->request.data.auth.require_membership_of_sid))) {
DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n",
- state->request.data.auth.user,
+ state->request.data.auth.user,
state->request.data.auth.require_membership_of_sid));
goto done;
}
@@ -1691,8 +1663,8 @@ process_result:
/* This is not entirely correct I believe, but it is
consistent. Only apply the password policy settings
- too warn users for our own domain. Cannot obtain these
- from trusted DCs all the time so don't do it at all.
+ too warn users for our own domain. Cannot obtain these
+ from trusted DCs all the time so don't do it at all.
-- jerry */
result = NT_STATUS_NOT_SUPPORTED;
@@ -1700,16 +1672,16 @@ process_result:
result = fillup_password_policy(our_domain, state);
}
- if (!NT_STATUS_IS_OK(result)
- && !NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED) )
+ if (!NT_STATUS_IS_OK(result)
+ && !NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED) )
{
- DEBUG(10,("Failed to get password policies for domain %s: %s\n",
+ DEBUG(10,("Failed to get password policies for domain %s: %s\n",
domain->name, nt_errstr(result)));
goto done;
}
}
- result = NT_STATUS_OK;
+ result = NT_STATUS_OK;
}
done:
@@ -1718,20 +1690,26 @@ done:
(NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
result = NT_STATUS_NO_LOGON_SERVERS;
}
+
+ state->response.data.auth.nt_status = NT_STATUS_V(result);
+ fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
- set_auth_errors(&state->response, result);
+ /* we might have given a more useful error above */
+ if (!*state->response.data.auth.error_string)
+ fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
+ state->response.data.auth.pam_error = nt_status_to_pam(result);
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n",
- state->request.data.auth.user,
+ DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n",
+ state->request.data.auth.user,
state->response.data.auth.nt_status_string,
- state->response.data.auth.pam_error));
+ state->response.data.auth.pam_error));
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
/**********************************************************************
- Challenge Response Authentication Protocol
+ Challenge Response Authentication Protocol
**********************************************************************/
void winbindd_pam_auth_crap(struct winbindd_cli_state *state)
@@ -1795,7 +1773,7 @@ void winbindd_pam_auth_crap(struct winbindd_cli_state *state)
set_auth_errors(&state->response, result);
DEBUG(5, ("CRAP authentication for %s\\%s returned %s (PAM: %d)\n",
state->request.data.auth_crap.domain,
- state->request.data.auth_crap.user,
+ state->request.data.auth_crap.user,
state->response.data.auth.nt_status_string,
state->response.data.auth.pam_error));
request_error(state);
@@ -1804,7 +1782,7 @@ void winbindd_pam_auth_crap(struct winbindd_cli_state *state)
enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
+ struct winbindd_cli_state *state)
{
NTSTATUS result;
struct netr_SamInfo3 *info3 = NULL;
@@ -1837,7 +1815,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
} else if (lp_winbind_use_default_domain()) {
name_domain = lp_workgroup();
} else {
- DEBUG(5,("no domain specified with username (%s) - failing auth\n",
+ DEBUG(5,("no domain specified with username (%s) - failing auth\n",
name_user));
result = NT_STATUS_NO_SUCH_USER;
goto done;
@@ -1845,7 +1823,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid,
name_domain, name_user));
-
+
if (*state->request.data.auth_crap.workstation) {
workstation = state->request.data.auth_crap.workstation;
} else {
@@ -1854,8 +1832,8 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp)
|| state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) {
- DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
- state->request.data.auth_crap.lm_resp_len,
+ DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
+ state->request.data.auth_crap.lm_resp_len,
state->request.data.auth_crap.nt_resp_len));
result = NT_STATUS_INVALID_PARAMETER;
goto done;
@@ -1867,11 +1845,11 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
state->request.data.auth_crap.nt_resp_len);
/* what domain should we contact? */
-
+
if ( IS_DC ) {
if (!(contact_domain = find_domain_from_name(name_domain))) {
- DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
- state->request.data.auth_crap.user, name_domain, name_user, name_domain));
+ DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
+ state->request.data.auth_crap.user, name_domain, name_user, name_domain));
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
@@ -1885,9 +1863,19 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
}
do {
- netlogon_fn_t logon_fn;
-
- retry = false;
+ NTSTATUS (*logon_fn)(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 logon_parameters,
+ const char *server,
+ const char *username,
+ const char *domain,
+ const char *workstation,
+ const uint8 chal[8],
+ DATA_BLOB lm_response,
+ DATA_BLOB nt_response,
+ struct netr_SamInfo3 **info3);
+
+ retry = False;
netlogon_pipe = NULL;
result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
@@ -1907,7 +1895,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
state->request.data.auth_crap.logon_parameters,
contact_domain->dcname,
name_user,
- name_domain,
+ name_domain,
/* Bug #3248 - found by Stefan Burkei. */
workstation, /* We carefully set this above so use it... */
state->request.data.auth_crap.chal,
@@ -1919,8 +1907,8 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
&& contact_domain->can_do_samlogon_ex) {
DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
"retrying with NetSamLogon\n"));
- contact_domain->can_do_samlogon_ex = false;
- retry = true;
+ contact_domain->can_do_samlogon_ex = False;
+ retry = True;
continue;
}
@@ -1931,14 +1919,14 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
our connection. */
if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) {
- retry = true;
+ retry = True;
continue;
}
/* if we get access denied, a possible cause was that we had and open
connection to the DC, but someone changed our machine account password
out from underneath us using 'net rpc changetrustpw' */
-
+
if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) ) {
DEBUG(3,("winbindd_pam_auth: sam_logon returned "
"ACCESS_DENIED. Maybe the trust account "
@@ -1946,8 +1934,8 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
"Killing connections to domain %s\n",
name_domain));
invalidate_cm_connection(&contact_domain->conn);
- retry = true;
- }
+ retry = True;
+ }
} while ( (attempts < 2) && retry );
@@ -1962,7 +1950,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
state->request.data.auth_crap.require_membership_of_sid))) {
DEBUG(3, ("User %s is not in the required group (%s), so "
"crap authentication is rejected\n",
- state->request.data.auth_crap.user,
+ state->request.data.auth_crap.user,
state->request.data.auth_crap.require_membership_of_sid));
goto done;
}
@@ -1985,14 +1973,21 @@ done:
result = nt_status_squash(result);
}
- set_auth_errors(&state->response, result);
+ state->response.data.auth.nt_status = NT_STATUS_V(result);
+ fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
+
+ /* we might have given a more useful error above */
+ if (!*state->response.data.auth.error_string) {
+ fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
+ }
+ state->response.data.auth.pam_error = nt_status_to_pam(result);
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
- ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n",
+ DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
+ ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n",
name_domain,
name_user,
state->response.data.auth.nt_status_string,
- state->response.data.auth.pam_error));
+ state->response.data.auth.pam_error));
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
@@ -2002,36 +1997,20 @@ done:
void winbindd_pam_chauthtok(struct winbindd_cli_state *state)
{
fstring domain, user;
- char *mapped_user;
struct winbindd_domain *contact_domain;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)state->pid,
state->request.data.chauthtok.user));
/* Setup crap */
- nt_status = normalize_name_unmap(state->mem_ctx,
- state->request.data.chauthtok.user,
- &mapped_user);
-
- /* Update the chauthtok name if we did any mapping */
-
- if (NT_STATUS_IS_OK(nt_status) ||
- NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
- {
- fstrcpy(state->request.data.chauthtok.user, mapped_user);
- }
-
- /* Must pass in state->...chauthtok.user because
- canonicalize_username() assumes an fstring(). Since
- we have already copied it (if necessary), this is ok. */
+ ws_name_return( state->request.data.auth.user, WB_REPLACE_CHAR );
if (!canonicalize_username(state->request.data.chauthtok.user, domain, user)) {
set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER);
DEBUG(5, ("winbindd_pam_chauthtok: canonicalize_username %s failed with %s"
"(PAM: %d)\n",
- state->request.data.auth.user,
+ state->request.data.auth.user,
state->response.data.auth.nt_status_string,
state->response.data.auth.pam_error));
request_error(state);
@@ -2041,8 +2020,8 @@ void winbindd_pam_chauthtok(struct winbindd_cli_state *state)
contact_domain = find_domain_from_name(domain);
if (!contact_domain) {
set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER);
- DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n",
- state->request.data.chauthtok.user, domain, user, domain));
+ DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n",
+ state->request.data.chauthtok.user, domain, user, domain));
request_error(state);
return;
}
@@ -2057,7 +2036,7 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
char *newpass = NULL;
POLICY_HND dom_pol;
struct rpc_pipe_client *cli;
- bool got_info = false;
+ bool got_info = False;
struct samr_DomInfo1 *info = NULL;
struct samr_ChangeReject *reject = NULL;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -2087,44 +2066,52 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
goto done;
}
- result = rpccli_samr_chgpasswd_user3(cli, state->mem_ctx,
- user,
- newpass,
- oldpass,
- &info,
- &reject);
+ result = rpccli_samr_chgpasswd3(cli, state->mem_ctx,
+ user,
+ newpass,
+ oldpass,
+ &info,
+ &reject);
/* Windows 2003 returns NT_STATUS_PASSWORD_RESTRICTION */
if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION) ) {
-
- fill_in_password_policy(&state->response, info);
+ state->response.data.auth.policy.min_length_password =
+ info->min_password_length;
+ state->response.data.auth.policy.password_history =
+ info->password_history_length;
+ state->response.data.auth.policy.password_properties =
+ info->password_properties;
+ state->response.data.auth.policy.expire =
+ nt_time_to_unix_abs((NTTIME *)&info->max_password_age);
+ state->response.data.auth.policy.min_passwordage =
+ nt_time_to_unix_abs((NTTIME *)&info->min_password_age);
state->response.data.auth.reject_reason =
reject->reason;
- got_info = true;
+ got_info = True;
}
- /* only fallback when the chgpasswd_user3 call is not supported */
+ /* only fallback when the chgpasswd3 call is not supported */
if ((NT_STATUS_EQUAL(result, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR))) ||
(NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) ||
(NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED))) {
- DEBUG(10,("Password change with chgpasswd_user3 failed with: %s, retrying chgpasswd_user2\n",
+ DEBUG(10,("Password change with chgpasswd3 failed with: %s, retrying chgpasswd_user\n",
nt_errstr(result)));
-
- result = rpccli_samr_chgpasswd_user2(cli, state->mem_ctx, user, newpass, oldpass);
+
+ result = rpccli_samr_chgpasswd_user(cli, state->mem_ctx, user, newpass, oldpass);
/* Windows 2000 returns NT_STATUS_ACCOUNT_RESTRICTION.
Map to the same status code as Windows 2003. */
if ( NT_STATUS_EQUAL(NT_STATUS_ACCOUNT_RESTRICTION, result ) ) {
- result = NT_STATUS_PASSWORD_RESTRICTION;
+ result = NT_STATUS_PASSWORD_RESTRICTION;
}
}
-done:
+done:
if (NT_STATUS_IS_OK(result) && (state->request.flags & WBFLAG_PAM_CACHED_LOGIN)) {
@@ -2172,7 +2159,7 @@ done:
if (!NT_STATUS_IS_OK(result) && !got_info && contact_domain) {
NTSTATUS policy_ret;
-
+
policy_ret = fillup_password_policy(contact_domain, state);
/* failure of this is non critical, it will just provide no
@@ -2187,14 +2174,17 @@ done:
process_result:
- set_auth_errors(&state->response, result);
+ state->response.data.auth.nt_status = NT_STATUS_V(result);
+ fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
+ fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
+ state->response.data.auth.pam_error = nt_status_to_pam(result);
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
- ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n",
+ DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
+ ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n",
domain,
user,
state->response.data.auth.nt_status_string,
- state->response.data.auth.pam_error));
+ state->response.data.auth.pam_error));
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
@@ -2229,7 +2219,7 @@ void winbindd_pam_logoff(struct winbindd_cli_state *state)
}
if ((sys_getpeereid(state->sock, &caller_uid)) != 0) {
- DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n",
+ DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n",
strerror(errno)));
goto failed;
}
@@ -2265,7 +2255,7 @@ void winbindd_pam_logoff(struct winbindd_cli_state *state)
}
enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
+ struct winbindd_cli_state *state)
{
NTSTATUS result = NT_STATUS_NOT_SUPPORTED;
@@ -2283,7 +2273,7 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
}
#ifdef HAVE_KRB5
-
+
if (state->request.data.logoff.uid < 0) {
DEBUG(0,("winbindd_pam_logoff: invalid uid\n"));
goto process_result;
@@ -2298,7 +2288,7 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
goto process_result;
}
- if (!ccache_entry_identical(state->request.data.logoff.user,
+ if (!ccache_entry_identical(state->request.data.logoff.user,
state->request.data.logoff.uid,
state->request.data.logoff.krb5ccname)) {
DEBUG(0,("winbindd_pam_logoff: cached entry differs.\n"));
@@ -2320,7 +2310,10 @@ process_result:
winbindd_delete_memory_creds(state->request.data.logoff.user);
- set_auth_errors(&state->response, result);
+ state->response.data.auth.nt_status = NT_STATUS_V(result);
+ fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
+ fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
+ state->response.data.auth.pam_error = nt_status_to_pam(result);
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
@@ -2337,12 +2330,12 @@ void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state)
sizeof(state->request.data.chng_pswd_auth_crap.user)-1]=0;
state->request.data.chng_pswd_auth_crap.domain[
sizeof(state->request.data.chng_pswd_auth_crap.domain)-1]=0;
-
+
DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n",
(unsigned long)state->pid,
state->request.data.chng_pswd_auth_crap.domain,
state->request.data.chng_pswd_auth_crap.user));
-
+
if (*state->request.data.chng_pswd_auth_crap.domain != '\0') {
domain_name = state->request.data.chng_pswd_auth_crap.domain;
} else if (lp_winbind_use_default_domain()) {
@@ -2362,7 +2355,7 @@ void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state)
set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER);
DEBUG(5, ("CRAP change password for %s\\%s returned %s (PAM: %d)\n",
state->request.data.chng_pswd_auth_crap.domain,
- state->request.data.chng_pswd_auth_crap.user,
+ state->request.data.chng_pswd_auth_crap.user,
state->response.data.auth.nt_status_string,
state->response.data.auth.pam_error));
request_error(state);
@@ -2388,7 +2381,7 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
sizeof(state->request.data.chng_pswd_auth_crap.domain)-1]=0;
*domain = 0;
*user = 0;
-
+
DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n",
(unsigned long)state->pid,
state->request.data.chng_pswd_auth_crap.domain,
@@ -2426,7 +2419,7 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n",
(unsigned long)state->pid, domain, user));
-
+
/* Change password */
new_nt_password = data_blob_talloc(
state->mem_ctx,
@@ -2465,15 +2458,18 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
cli, state->mem_ctx, user, new_nt_password, old_nt_hash_enc,
new_lm_password, old_lm_hash_enc);
- done:
-
- set_auth_errors(&state->response, result);
+ done:
+ state->response.data.auth.nt_status = NT_STATUS_V(result);
+ fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
+ fstrcpy(state->response.data.auth.error_string,
+ get_friendly_nt_error_msg(result));
+ state->response.data.auth.pam_error = nt_status_to_pam(result);
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
- ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n",
+ DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
+ ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n",
domain, user,
state->response.data.auth.nt_status_string,
- state->response.data.auth.pam_error));
+ state->response.data.auth.pam_error));
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
diff --git a/source/winbindd/winbindd_proto.h b/source/winbindd/winbindd_proto.h
deleted file mode 100644
index 4774bc8106..0000000000
--- a/source/winbindd/winbindd_proto.h
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * collected prototypes header
- *
- * frozen from "make proto" in May 2008
- *
- * Copyright (C) Michael Adam 2008
- *
- * 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
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _WINBINDD_PROTO_H_
-#define _WINBINDD_PROTO_H_
-
-
-/* The following definitions come from auth/token_util.c */
-
-bool nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token );
-bool nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid );
-NT_USER_TOKEN *get_root_nt_token( void );
-NTSTATUS add_aliases(const DOM_SID *domain_sid,
- struct nt_user_token *token);
-struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
- bool is_guest,
- int num_groupsids,
- const DOM_SID *groupsids);
-void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token);
-void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
- int n_groups, gid_t *groups);
-
-/* The following definitions come from smbd/connection.c */
-
-bool yield_connection(connection_struct *conn, const char *name);
-int count_current_connections( const char *sharename, bool clear );
-int count_all_current_connections(void);
-bool claim_connection(connection_struct *conn, const char *name,
- uint32 msg_flags);
-bool register_message_flags(bool doreg, uint32 msg_flags);
-bool store_pipe_opendb( smb_np_struct *p );
-bool delete_pipe_opendb( smb_np_struct *p );
-
-/* The following definitions come from winbindd/winbindd.c */
-
-struct event_context *winbind_event_context(void);
-struct messaging_context *winbind_messaging_context(void);
-void add_fd_event(struct fd_event *ev);
-void remove_fd_event(struct fd_event *ev);
-void setup_async_read(struct fd_event *event, void *data, size_t length,
- void (*finished)(void *private_data, bool success),
- void *private_data);
-void setup_async_write(struct fd_event *event, void *data, size_t length,
- void (*finished)(void *private_data, bool success),
- void *private_data);
-void request_error(struct winbindd_cli_state *state);
-void request_ok(struct winbindd_cli_state *state);
-void winbind_check_sighup(const char *logfile);
-void winbind_check_sigterm(bool in_parent);
-int main(int argc, char **argv, char **envp);
-
-/* The following definitions come from winbindd/winbindd_ads.c */
-
-
-/* The following definitions come from winbindd/winbindd_async.c */
-
-void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child,
- const struct winbindd_request *request,
- void (*cont)(TALLOC_CTX *mem_ctx, bool success,
- struct winbindd_response *response,
- void *c, void *private_data),
- void *c, void *private_data);
-void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
- const struct winbindd_request *request,
- void (*cont)(TALLOC_CTX *mem_ctx, bool success,
- struct winbindd_response *response,
- void *c, void *private_data),
- void *c, void *private_data);
-void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
- void (*cont)(void *private_data, bool success,
- const char *dom_name,
- const char *name,
- enum lsa_SidType type),
- void *private_data);
-enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_lookupname_async(TALLOC_CTX *mem_ctx,
- const char *dom_name, const char *name,
- void (*cont)(void *private_data, bool success,
- const DOM_SID *sid,
- enum lsa_SidType type),
- enum winbindd_cmd orig_cmd,
- void *private_data);
-enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_listent_async(TALLOC_CTX *mem_ctx,
- struct winbindd_domain *domain,
- void (*cont)(void *private_data, bool success,
- fstring dom_name, char* extra_data),
- void *private_data, enum ent_type type);
-enum winbindd_result winbindd_dual_list_users(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_list_groups(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,
- size_t num_sids, char **result, ssize_t *len);
-enum winbindd_result winbindd_dual_lookuprids(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_getsidaliases_async(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sids, size_t num_sids,
- void (*cont)(void *private_data,
- bool success,
- const DOM_SID *aliases,
- size_t num_aliases),
- void *private_data);
-enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_gettoken_async(TALLOC_CTX *mem_ctx, const DOM_SID *user_sid,
- void (*cont)(void *private_data, bool success,
- DOM_SID *sids, size_t num_sids),
- void *private_data);
-void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
- const DOM_SID *sid,
- void (*cont)(void *private_data, bool success,
- const char *acct_name,
- const char *full_name,
- const char *homedir,
- const char *shell,
- gid_t gid,
- uint32 group_rid),
- void *private_data);
-
-/* The following definitions come from winbindd/winbindd_cache.c */
-
-void winbindd_check_cache_size(time_t t);
-struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status);
-NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const DOM_SID *sid);
-NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- const uint8 **cached_nt_pass,
- const uint8 **cached_salt);
-NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- const uint8 nt_pass[NT_HASH_LEN]);
-void wcache_invalidate_samlogon(struct winbindd_domain *domain,
- struct netr_SamInfo3 *info3);
-bool wcache_invalidate_cache(void);
-bool init_wcache(void);
-bool initialize_winbindd_cache(void);
-void close_winbindd_cache(void);
-void cache_store_response(pid_t pid, struct winbindd_response *response);
-bool cache_retrieve_response(pid_t pid, struct winbindd_response * response);
-void cache_cleanup_response(pid_t pid);
-bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
- char **domain_name, char **name,
- enum lsa_SidType *type);
-bool lookup_cached_name(TALLOC_CTX *mem_ctx,
- const char *domain_name,
- const char *name,
- DOM_SID *sid,
- enum lsa_SidType *type);
-void cache_name2sid(struct winbindd_domain *domain,
- const char *domain_name, const char *name,
- enum lsa_SidType type, const DOM_SID *sid);
-void wcache_flush_cache(void);
-NTSTATUS wcache_count_cached_creds(struct winbindd_domain *domain, int *count);
-NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const DOM_SID *sid) ;
-bool set_global_winbindd_state_offline(void);
-void set_global_winbindd_state_online(void);
-bool get_global_winbindd_state_offline(void);
-int winbindd_validate_cache(void);
-int winbindd_validate_cache_nobackup(void);
-bool winbindd_cache_validate_and_initialize(void);
-bool wcache_tdc_fetch_list( struct winbindd_tdc_domain **domains, size_t *num_domains );
-bool wcache_tdc_add_domain( struct winbindd_domain *domain );
-struct winbindd_tdc_domain * wcache_tdc_fetch_domain( TALLOC_CTX *ctx, const char *name );
-void wcache_tdc_clear( void );
-NTSTATUS nss_get_info_cached( struct winbindd_domain *domain,
- const DOM_SID *user_sid,
- TALLOC_CTX *ctx,
- ADS_STRUCT *ads, LDAPMessage *msg,
- char **homedir, char **shell, char **gecos,
- gid_t *p_gid);
-
-/* The following definitions come from winbindd/winbindd_ccache_access.c */
-
-void winbindd_ccache_ntlm_auth(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-
-/* The following definitions come from winbindd/winbindd_cm.c */
-
-void set_domain_offline(struct winbindd_domain *domain);
-void set_domain_online_request(struct winbindd_domain *domain);
-void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,
- const char *server,
- NTSTATUS result);
-void invalidate_cm_connection(struct winbindd_cm_conn *conn);
-void close_conns_after_fork(void);
-NTSTATUS init_dc_connection(struct winbindd_domain *domain);
-NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
- struct rpc_pipe_client **cli, POLICY_HND *sam_handle);
-NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
- struct rpc_pipe_client **cli, POLICY_HND *lsa_policy);
-NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
- struct rpc_pipe_client **cli);
-
-/* The following definitions come from winbindd/winbindd_cred_cache.c */
-
-bool ccache_entry_exists(const char *username);
-bool ccache_entry_identical(const char *username,
- uid_t uid,
- const char *ccname);
-NTSTATUS add_ccache_to_list(const char *princ_name,
- const char *ccname,
- const char *service,
- const char *username,
- const char *realm,
- uid_t uid,
- time_t create_time,
- time_t ticket_end,
- time_t renew_until,
- bool postponed_request);
-NTSTATUS remove_ccache(const char *username);
-struct WINBINDD_MEMORY_CREDS *find_memory_creds_by_name(const char *username);
-NTSTATUS winbindd_add_memory_creds(const char *username,
- uid_t uid,
- const char *pass);
-NTSTATUS winbindd_delete_memory_creds(const char *username);
-NTSTATUS winbindd_replace_memory_creds(const char *username,
- const char *pass);
-
-/* The following definitions come from winbindd/winbindd_creds.c */
-
-NTSTATUS winbindd_get_creds(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- struct netr_SamInfo3 **info3,
- const uint8 *cached_nt_pass[NT_HASH_LEN],
- const uint8 *cred_salt[NT_HASH_LEN]);
-NTSTATUS winbindd_store_creds(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *user,
- const char *pass,
- struct netr_SamInfo3 *info3,
- const DOM_SID *user_sid);
-NTSTATUS winbindd_update_creds_by_info3(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *user,
- const char *pass,
- struct netr_SamInfo3 *info3);
-NTSTATUS winbindd_update_creds_by_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- const char *pass);
-NTSTATUS winbindd_update_creds_by_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *user,
- const char *pass);
-
-/* The following definitions come from winbindd/winbindd_domain.c */
-
-void setup_domain_child(struct winbindd_domain *domain,
- struct winbindd_child *child);
-
-/* The following definitions come from winbindd/winbindd_dual.c */
-
-void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child,
- struct winbindd_request *request,
- struct winbindd_response *response,
- void (*continuation)(void *private_data, bool success),
- void *private_data);
-void async_domain_request(TALLOC_CTX *mem_ctx,
- struct winbindd_domain *domain,
- struct winbindd_request *request,
- struct winbindd_response *response,
- void (*continuation)(void *private_data_data, bool success),
- void *private_data_data);
-void sendto_child(struct winbindd_cli_state *state,
- struct winbindd_child *child);
-void sendto_domain(struct winbindd_cli_state *state,
- struct winbindd_domain *domain);
-void setup_child(struct winbindd_child *child,
- const struct winbindd_child_dispatch_table *table,
- const char *logprefix,
- const char *logname);
-void winbind_child_died(pid_t pid);
-void winbindd_flush_negative_conn_cache(struct winbindd_domain *domain);
-void winbind_msg_debug(struct messaging_context *msg_ctx,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data);
-void winbind_msg_offline(struct messaging_context *msg_ctx,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data);
-void winbind_msg_online(struct messaging_context *msg_ctx,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data);
-void winbind_msg_onlinestatus(struct messaging_context *msg_ctx,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data);
-void winbind_msg_dump_event_list(struct messaging_context *msg_ctx,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data);
-void winbind_msg_dump_domain_list(struct messaging_context *msg_ctx,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data);
-
-/* The following definitions come from winbindd/winbindd_group.c */
-
-void winbindd_getgrnam(struct winbindd_cli_state *state);
-void winbindd_getgrgid(struct winbindd_cli_state *state);
-void winbindd_setgrent(struct winbindd_cli_state *state);
-void winbindd_endgrent(struct winbindd_cli_state *state);
-void winbindd_getgrent(struct winbindd_cli_state *state);
-void winbindd_list_groups(struct winbindd_cli_state *state);
-void winbindd_getgroups(struct winbindd_cli_state *state);
-void winbindd_getusersids(struct winbindd_cli_state *state);
-void winbindd_getuserdomgroups(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-bool get_sam_group_entries(struct getent_state *ent);
-
-
-/* The following definitions come from winbindd/winbindd_idmap.c */
-
-void init_idmap_child(void);
-struct winbindd_child *idmap_child(void);
-void winbindd_set_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map,
- void (*cont)(void *private_data, bool success),
- void *private_data);
-enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_set_hwm_async(TALLOC_CTX *mem_ctx, const struct unixid *xid,
- void (*cont)(void *private_data, bool success),
- void *private_data);
-enum winbindd_result winbindd_dual_set_hwm(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_sids2xids_async(TALLOC_CTX *mem_ctx, void *sids, int size,
- void (*cont)(void *private_data, bool success, void *data, int len),
- void *private_data);
-enum winbindd_result winbindd_dual_sids2xids(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
- void (*cont)(void *private_data, bool success, uid_t uid),
- void *private_data);
-enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
- void (*cont)(void *private_data, bool success, gid_t gid),
- void *private_data);
-enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_uid2sid_async(TALLOC_CTX *mem_ctx, uid_t uid,
- void (*cont)(void *private_data, bool success, const char *sid),
- void *private_data);
-enum winbindd_result winbindd_dual_uid2sid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_gid2sid_async(TALLOC_CTX *mem_ctx, gid_t gid,
- void (*cont)(void *private_data, bool success, const char *sid),
- void *private_data);
-enum winbindd_result winbindd_dual_gid2sid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-
-/* The following definitions come from winbindd/winbindd_locator.c */
-
-void init_locator_child(void);
-struct winbindd_child *locator_child(void);
-void winbindd_dsgetdcname(struct winbindd_cli_state *state);
-
-/* The following definitions come from winbindd/winbindd_misc.c */
-
-void winbindd_check_machine_acct(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_list_ent(struct winbindd_cli_state *state, enum ent_type type);
-void winbindd_list_trusted_domains(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_getdcname(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_show_sequence(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_domain_info(struct winbindd_cli_state *state);
-void winbindd_ping(struct winbindd_cli_state *state);
-void winbindd_info(struct winbindd_cli_state *state);
-void winbindd_interface_version(struct winbindd_cli_state *state);
-void winbindd_domain_name(struct winbindd_cli_state *state);
-void winbindd_netbios_name(struct winbindd_cli_state *state);
-void winbindd_priv_pipe_dir(struct winbindd_cli_state *state);
-
-/* The following definitions come from winbindd/winbindd_ndr.c */
-
-void ndr_print_winbindd_child(struct ndr_print *ndr,
- const char *name,
- const struct winbindd_child *r);
-void ndr_print_winbindd_cm_conn(struct ndr_print *ndr,
- const char *name,
- const struct winbindd_cm_conn *r);
-void ndr_print_winbindd_methods(struct ndr_print *ndr,
- const char *name,
- const struct winbindd_methods *r);
-void ndr_print_winbindd_domain(struct ndr_print *ndr,
- const char *name,
- const struct winbindd_domain *r);
-
-/* The following definitions come from winbindd/winbindd_pam.c */
-
-struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state,
- const char *domain_name);
-void winbindd_pam_auth(struct winbindd_cli_state *state);
-NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
- struct winbindd_cli_state *state,
- struct netr_SamInfo3 **info3);
-NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain,
- struct winbindd_cli_state *state,
- struct netr_SamInfo3 **info3);
-NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
- struct winbindd_cli_state *state,
- struct netr_SamInfo3 **info3);
-enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
- struct winbindd_cli_state *state) ;
-void winbindd_pam_auth_crap(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
- struct winbindd_cli_state *state) ;
-void winbindd_pam_chauthtok(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact_domain,
- struct winbindd_cli_state *state);
-void winbindd_pam_logoff(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
- struct winbindd_cli_state *state) ;
-void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state);
-
-/* The following definitions come from winbindd/winbindd_passdb.c */
-
-
-/* The following definitions come from winbindd/winbindd_reconnect.c */
-
-
-/* The following definitions come from winbindd/winbindd_rpc.c */
-
-NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- enum winbindd_cmd original_cmd,
- const char *domain_name,
- const char *name,
- DOM_SID *sid,
- enum lsa_SidType *type);
-NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- char **domain_name,
- char **name,
- enum lsa_SidType *type);
-NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- uint32 *rids,
- size_t num_rids,
- char **domain_name,
- char ***names,
- enum lsa_SidType **types);
-NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 num_sids, const DOM_SID *sids,
- uint32 *num_aliases, uint32 **alias_rids);
-NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo12 *lockout_policy);
-NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo1 *password_policy);
-
-/* The following definitions come from winbindd/winbindd_sid.c */
-
-void winbindd_lookupsid(struct winbindd_cli_state *state);
-void winbindd_lookupname(struct winbindd_cli_state *state);
-void winbindd_lookuprids(struct winbindd_cli_state *state);
-void winbindd_sid_to_uid(struct winbindd_cli_state *state);
-void winbindd_sid_to_gid(struct winbindd_cli_state *state);
-void winbindd_sids_to_unixids(struct winbindd_cli_state *state);
-void winbindd_set_mapping(struct winbindd_cli_state *state);
-void winbindd_set_hwm(struct winbindd_cli_state *state);
-void winbindd_uid_to_sid(struct winbindd_cli_state *state);
-void winbindd_gid_to_sid(struct winbindd_cli_state *state);
-void winbindd_allocate_uid(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_allocate_uid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_allocate_gid(struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_allocate_gid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-
-/* The following definitions come from winbindd/winbindd_user.c */
-
-enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-void winbindd_getpwnam(struct winbindd_cli_state *state);
-void winbindd_getpwuid(struct winbindd_cli_state *state);
-void winbindd_setpwent(struct winbindd_cli_state *state);
-void winbindd_endpwent(struct winbindd_cli_state *state);
-void winbindd_getpwent(struct winbindd_cli_state *state);
-void winbindd_list_users(struct winbindd_cli_state *state);
-
-/* The following definitions come from winbindd/winbindd_util.c */
-
-struct winbindd_domain *domain_list(void);
-void free_domain_list(void);
-void rescan_trusted_domains( void );
-enum winbindd_result init_child_connection(struct winbindd_domain *domain,
- void (*continuation)(void *private_data,
- bool success),
- void *private_data);
-enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
-bool init_domain_list(void);
-void check_domain_trusted( const char *name, const DOM_SID *user_sid );
-struct winbindd_domain *find_domain_from_name_noinit(const char *domain_name);
-struct winbindd_domain *find_domain_from_name(const char *domain_name);
-struct winbindd_domain *find_domain_from_sid_noinit(const DOM_SID *sid);
-struct winbindd_domain *find_domain_from_sid(const DOM_SID *sid);
-struct winbindd_domain *find_our_domain(void);
-struct winbindd_domain *find_root_domain(void);
-struct winbindd_domain *find_builtin_domain(void);
-struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid);
-struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name);
-bool winbindd_lookup_sid_by_name(TALLOC_CTX *mem_ctx,
- enum winbindd_cmd orig_cmd,
- struct winbindd_domain *domain,
- const char *domain_name,
- const char *name, DOM_SID *sid,
- enum lsa_SidType *type);
-bool winbindd_lookup_name_by_sid(TALLOC_CTX *mem_ctx,
- struct winbindd_domain *domain,
- DOM_SID *sid,
- char **dom_name,
- char **name,
- enum lsa_SidType *type);
-void free_getent_state(struct getent_state *state);
-bool parse_domain_user(const char *domuser, fstring domain, fstring user);
-bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser,
- char **domain, char **user);
-void parse_add_domuser(void *buf, char *domuser, int *len);
-bool canonicalize_username(fstring username_inout, fstring domain, fstring user);
-void fill_domain_username(fstring name, const char *domain, const char *user, bool can_assume);
-const char *get_winbind_pipe_dir(void) ;
-char *get_winbind_priv_pipe_dir(void) ;
-int open_winbindd_socket(void);
-int open_winbindd_priv_socket(void);
-void close_winbindd_socket(void);
-struct winbindd_cli_state *winbindd_client_list(void);
-void winbindd_add_client(struct winbindd_cli_state *cli);
-void winbindd_remove_client(struct winbindd_cli_state *cli);
-void winbindd_kill_all_clients(void);
-int winbindd_num_clients(void);
-NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
- uint32 *p_num_groups, DOM_SID **user_sids);
-
-NTSTATUS normalize_name_map(TALLOC_CTX *mem_ctx,
- struct winbindd_domain *domain,
- char *name,
- char **normalized);
-NTSTATUS normalize_name_unmap(TALLOC_CTX *mem_ctx,
- char *name,
- char **normalized);
-
-NTSTATUS resolve_username_to_alias(TALLOC_CTX *mem_ctx,
- struct winbindd_domain *domain,
- const char *name, char **alias);
-NTSTATUS resolve_alias_to_username(TALLOC_CTX *mem_ctx,
- struct winbindd_domain *domain,
- const char *alias, char **name);
-
-bool winbindd_can_contact_domain(struct winbindd_domain *domain);
-bool winbindd_internal_child(struct winbindd_child *child);
-void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain);
-void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain);
-void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain);
-void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain);
-void set_auth_errors(struct winbindd_response *resp, NTSTATUS result);
-
-/* The following definitions come from winbindd/winbindd_wins.c */
-
-void winbindd_wins_byip(struct winbindd_cli_state *state);
-void winbindd_wins_byname(struct winbindd_cli_state *state);
-
-#endif /* _WINBINDD_PROTO_H_ */
diff --git a/source/winbindd/winbindd_rpc.c b/source/winbindd/winbindd_rpc.c
index df80ad8029..2a7704c8a5 100644
--- a/source/winbindd/winbindd_rpc.c
+++ b/source/winbindd/winbindd_rpc.c
@@ -279,8 +279,6 @@ NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
char *full_name = NULL;
struct rpc_pipe_client *cli;
POLICY_HND lsa_policy;
- NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
- char *mapped_name = NULL;
if (name == NULL || *name=='\0') {
full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
@@ -296,19 +294,9 @@ NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
- name_map_status = normalize_name_unmap(mem_ctx, full_name,
- &mapped_name);
+ ws_name_return( full_name, WB_REPLACE_CHAR );
- /* Reset the full_name pointer if we mapped anytthing */
-
- if (NT_STATUS_IS_OK(name_map_status) ||
- NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
- {
- full_name = mapped_name;
- }
-
- DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
- full_name?full_name:"", domain_name ));
+ DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name?full_name:"", domain_name ));
result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
if (!NT_STATUS_IS_OK(result))
@@ -344,8 +332,6 @@ NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
NTSTATUS result;
struct rpc_pipe_client *cli;
POLICY_HND lsa_policy;
- NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
- char *mapped_name = NULL;
DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
domain->name ));
@@ -370,17 +356,9 @@ NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
*domain_name = domains[0];
*name = names[0];
+ ws_name_replace( *name, WB_REPLACE_CHAR );
+
DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
-
- name_map_status = normalize_name_map(mem_ctx, domain, *name,
- &mapped_name);
- if (NT_STATUS_IS_OK(name_map_status) ||
- NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
- {
- *name = mapped_name;
- DEBUG(5,("returning mapped name -- %s\n", *name));
- }
-
return NT_STATUS_OK;
}
@@ -433,20 +411,8 @@ NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
ret_names = *names;
for (i=0; i<num_rids; i++) {
- NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
- char *mapped_name = NULL;
-
if ((*types)[i] != SID_NAME_UNKNOWN) {
- name_map_status = normalize_name_map(mem_ctx,
- domain,
- ret_names[i],
- &mapped_name);
- if (NT_STATUS_IS_OK(name_map_status) ||
- NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
- {
- ret_names[i] = mapped_name;
- }
-
+ ws_name_replace( ret_names[i], WB_REPLACE_CHAR );
*domain_name = domains[i];
}
}
@@ -784,14 +750,14 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
/* This call can take a long time - allow the server to time out.
35 seconds should do it. */
- orig_timeout = rpccli_set_timeout(cli, 35000);
+ orig_timeout = cli_set_timeout(cli->cli, 35000);
result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
&group_pol,
&rids);
/* And restore our original timeout. */
- rpccli_set_timeout(cli, orig_timeout);
+ cli_set_timeout(cli->cli, orig_timeout);
rpccli_samr_Close(cli, mem_ctx, &group_pol);
diff --git a/source/winbindd/winbindd_sid.c b/source/winbindd/winbindd_sid.c
index 274786fa63..0e8e6ca00b 100644
--- a/source/winbindd/winbindd_sid.c
+++ b/source/winbindd/winbindd_sid.c
@@ -159,9 +159,6 @@ static void sid2uid_recv(void *private_data, bool success, uid_t uid)
{
struct winbindd_cli_state *state =
talloc_get_type_abort(private_data, struct winbindd_cli_state);
- struct dom_sid sid;
-
- string_to_sid(&sid, state->request.data.sid);
if (!success) {
DEBUG(5, ("Could not convert sid %s\n",
@@ -183,44 +180,34 @@ static void sid2uid_lookupsid_recv( void *private_data, bool success,
talloc_get_type_abort(private_data, struct winbindd_cli_state);
DOM_SID sid;
- if (!string_to_sid(&sid, state->request.data.sid)) {
- DEBUG(1, ("sid2uid_lookupsid_recv: Could not get convert sid "
- "%s from string\n", state->request.data.sid));
- request_error(state);
- return;
- }
-
if (!success) {
DEBUG(5, ("sid2uid_lookupsid_recv Could not convert get sid type for %s\n",
state->request.data.sid));
- goto fail;
+ request_error(state);
+ return;
}
if ( (type!=SID_NAME_USER) && (type!=SID_NAME_COMPUTER) ) {
DEBUG(5,("sid2uid_lookupsid_recv: Sid %s is not a user or a computer.\n",
state->request.data.sid));
- goto fail;
+ request_error(state);
+ return;
}
+ if (!string_to_sid(&sid, state->request.data.sid)) {
+ DEBUG(1, ("sid2uid_lookupsid_recv: Could not get convert sid %s from string\n",
+ state->request.data.sid));
+ request_error(state);
+ return;
+ }
+
/* always use the async interface (may block) */
winbindd_sid2uid_async(state->mem_ctx, &sid, sid2uid_recv, state);
- return;
-
- fail:
- /*
- * We have to set the cache ourselves here, the child which is
- * normally responsible was not queried yet.
- */
- idmap_cache_set_sid2uid(&sid, -1);
- request_error(state);
- return;
}
void winbindd_sid_to_uid(struct winbindd_cli_state *state)
{
DOM_SID sid;
- uid_t uid;
- bool expired;
/* Ensure null termination */
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
@@ -235,29 +222,10 @@ void winbindd_sid_to_uid(struct winbindd_cli_state *state)
return;
}
- if (idmap_cache_find_sid2uid(&sid, &uid, &expired)) {
- DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n",
- (int)uid, expired ? " (expired)": ""));
- if (expired && IS_DOMAIN_ONLINE(find_our_domain())) {
- DEBUG(10, ("revalidating expired entry\n"));
- goto backend;
- }
- if (uid == -1) {
- DEBUG(10, ("Returning negative cache entry\n"));
- request_error(state);
- return;
- }
- DEBUG(10, ("Returning positive cache entry\n"));
- state->response.data.uid = uid;
- request_ok(state);
- return;
- }
-
/* Validate the SID as a user. Hopefully this will hit cache.
Needed to prevent DoS by exhausting the uid allocation
range from random SIDs. */
- backend:
winbindd_lookupsid_async( state->mem_ctx, &sid, sid2uid_lookupsid_recv, state );
}
@@ -268,9 +236,6 @@ static void sid2gid_recv(void *private_data, bool success, gid_t gid)
{
struct winbindd_cli_state *state =
talloc_get_type_abort(private_data, struct winbindd_cli_state);
- struct dom_sid sid;
-
- string_to_sid(&sid, state->request.data.sid);
if (!success) {
DEBUG(5, ("Could not convert sid %s\n",
@@ -292,17 +257,11 @@ static void sid2gid_lookupsid_recv( void *private_data, bool success,
talloc_get_type_abort(private_data, struct winbindd_cli_state);
DOM_SID sid;
- if (!string_to_sid(&sid, state->request.data.sid)) {
- DEBUG(1, ("sid2gid_lookupsid_recv: Could not get convert sid "
- "%s from string\n", state->request.data.sid));
- request_error(state);
- return;
- }
-
if (!success) {
DEBUG(5, ("sid2gid_lookupsid_recv: Could not get sid type for %s\n",
state->request.data.sid));
- goto fail;
+ request_error(state);
+ return;
}
if ( (type!=SID_NAME_DOM_GRP) &&
@@ -311,28 +270,24 @@ static void sid2gid_lookupsid_recv( void *private_data, bool success,
{
DEBUG(5,("sid2gid_lookupsid_recv: Sid %s is not a group.\n",
state->request.data.sid));
- goto fail;
+ request_error(state);
+ return;
}
+ if (!string_to_sid(&sid, state->request.data.sid)) {
+ DEBUG(1, ("sid2gid_lookupsid_recv: Could not get convert sid %s from string\n",
+ state->request.data.sid));
+ request_error(state);
+ return;
+ }
+
/* always use the async interface (may block) */
winbindd_sid2gid_async(state->mem_ctx, &sid, sid2gid_recv, state);
- return;
-
- fail:
- /*
- * We have to set the cache ourselves here, the child which is
- * normally responsible was not queried yet.
- */
- idmap_cache_set_sid2gid(&sid, -1);
- request_error(state);
- return;
}
void winbindd_sid_to_gid(struct winbindd_cli_state *state)
{
DOM_SID sid;
- gid_t gid;
- bool expired;
/* Ensure null termination */
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
@@ -347,32 +302,39 @@ void winbindd_sid_to_gid(struct winbindd_cli_state *state)
return;
}
- if (idmap_cache_find_sid2gid(&sid, &gid, &expired)) {
- DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n",
- (int)gid, expired ? " (expired)": ""));
- if (expired && IS_DOMAIN_ONLINE(find_our_domain())) {
- DEBUG(10, ("revalidating expired entry\n"));
- goto backend;
- }
- if (gid == -1) {
- DEBUG(10, ("Returning negative cache entry\n"));
- request_error(state);
- return;
- }
- DEBUG(10, ("Returning positive cache entry\n"));
- state->response.data.gid = gid;
- request_ok(state);
- return;
- }
-
/* Validate the SID as a group. Hopefully this will hit cache.
Needed to prevent DoS by exhausting the uid allocation
range from random SIDs. */
- backend:
winbindd_lookupsid_async( state->mem_ctx, &sid, sid2gid_lookupsid_recv, state );
}
+static void sids2xids_recv(void *private_data, bool success, void *data, int len)
+{
+ struct winbindd_cli_state *state =
+ talloc_get_type_abort(private_data, struct winbindd_cli_state);
+
+ if (!success) {
+ DEBUG(5, ("Could not convert sids to xids\n"));
+ request_error(state);
+ return;
+ }
+
+ state->response.extra_data.data = data;
+ state->response.length = sizeof(state->response) + len;
+ request_ok(state);
+}
+
+void winbindd_sids_to_unixids(struct winbindd_cli_state *state)
+{
+ DEBUG(3, ("[%5lu]: sids to xids\n", (unsigned long)state->pid));
+
+ winbindd_sids2xids_async(state->mem_ctx,
+ state->request.extra_data.data,
+ state->request.extra_len,
+ sids2xids_recv, state);
+}
+
static void set_mapping_recv(void *private_data, bool success)
{
struct winbindd_cli_state *state =
@@ -449,117 +411,60 @@ void winbindd_set_hwm(struct winbindd_cli_state *state)
/* Convert a uid to a sid */
-static void uid2sid_recv(void *private_data, bool success, const char *sidstr)
+static void uid2sid_recv(void *private_data, bool success, const char *sid)
{
struct winbindd_cli_state *state =
(struct winbindd_cli_state *)private_data;
- struct dom_sid sid;
- if (!success || !string_to_sid(&sid, sidstr)) {
- ZERO_STRUCT(sid);
- idmap_cache_set_sid2uid(&sid, state->request.data.uid);
- request_error(state);
+ if (success) {
+ DEBUG(10,("uid2sid: uid %lu has sid %s\n",
+ (unsigned long)(state->request.data.uid), sid));
+ fstrcpy(state->response.data.sid.sid, sid);
+ state->response.data.sid.type = SID_NAME_USER;
+ request_ok(state);
return;
}
- DEBUG(10,("uid2sid: uid %lu has sid %s\n",
- (unsigned long)(state->request.data.uid), sidstr));
-
- idmap_cache_set_sid2uid(&sid, state->request.data.uid);
- fstrcpy(state->response.data.sid.sid, sidstr);
- state->response.data.sid.type = SID_NAME_USER;
- request_ok(state);
+ request_error(state);
return;
}
void winbindd_uid_to_sid(struct winbindd_cli_state *state)
{
- struct dom_sid sid;
- bool expired;
-
DEBUG(3, ("[%5lu]: uid to sid %lu\n", (unsigned long)state->pid,
(unsigned long)state->request.data.uid));
- if (idmap_cache_find_uid2sid(state->request.data.uid, &sid,
- &expired)) {
- DEBUG(10, ("idmap_cache_find_uid2sid found %d%s\n",
- (int)state->request.data.uid,
- expired ? " (expired)": ""));
- if (expired && IS_DOMAIN_ONLINE(find_our_domain())) {
- DEBUG(10, ("revalidating expired entry\n"));
- goto backend;
- }
- if (is_null_sid(&sid)) {
- DEBUG(10, ("Returning negative cache entry\n"));
- request_error(state);
- return;
- }
- DEBUG(10, ("Returning positive cache entry\n"));
- sid_to_fstring(state->response.data.sid.sid, &sid);
- request_ok(state);
- return;
- }
-
/* always go via the async interface (may block) */
- backend:
winbindd_uid2sid_async(state->mem_ctx, state->request.data.uid, uid2sid_recv, state);
}
/* Convert a gid to a sid */
-static void gid2sid_recv(void *private_data, bool success, const char *sidstr)
+static void gid2sid_recv(void *private_data, bool success, const char *sid)
{
struct winbindd_cli_state *state =
(struct winbindd_cli_state *)private_data;
- struct dom_sid sid;
- if (!success || !string_to_sid(&sid, sidstr)) {
- ZERO_STRUCT(sid);
- idmap_cache_set_sid2gid(&sid, state->request.data.gid);
- request_error(state);
+ if (success) {
+ DEBUG(10,("gid2sid: gid %lu has sid %s\n",
+ (unsigned long)(state->request.data.gid), sid));
+ fstrcpy(state->response.data.sid.sid, sid);
+ state->response.data.sid.type = SID_NAME_DOM_GRP;
+ request_ok(state);
return;
}
- DEBUG(10,("gid2sid: gid %lu has sid %s\n",
- (unsigned long)(state->request.data.gid), sidstr));
- idmap_cache_set_sid2gid(&sid, state->request.data.gid);
- fstrcpy(state->response.data.sid.sid, sidstr);
- state->response.data.sid.type = SID_NAME_DOM_GRP;
- request_ok(state);
+ request_error(state);
return;
}
void winbindd_gid_to_sid(struct winbindd_cli_state *state)
{
- struct dom_sid sid;
- bool expired;
-
DEBUG(3, ("[%5lu]: gid to sid %lu\n", (unsigned long)state->pid,
(unsigned long)state->request.data.gid));
- if (idmap_cache_find_gid2sid(state->request.data.gid, &sid,
- &expired)) {
- DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n",
- (int)state->request.data.gid,
- expired ? " (expired)": ""));
- if (expired && IS_DOMAIN_ONLINE(find_our_domain())) {
- DEBUG(10, ("revalidating expired entry\n"));
- goto backend;
- }
- if (is_null_sid(&sid)) {
- DEBUG(10, ("Returning negative cache entry\n"));
- request_error(state);
- return;
- }
- DEBUG(10, ("Returning positive cache entry\n"));
- sid_to_fstring(state->response.data.sid.sid, &sid);
- request_ok(state);
- return;
- }
-
/* always use async calls (may block) */
- backend:
winbindd_gid2sid_async(state->mem_ctx, state->request.data.gid, gid2sid_recv, state);
}
diff --git a/source/winbindd/winbindd_user.c b/source/winbindd/winbindd_user.c
index e5d0a22a73..19feec38db 100644
--- a/source/winbindd/winbindd_user.c
+++ b/source/winbindd/winbindd_user.c
@@ -27,12 +27,12 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
-static bool fillup_pw_field(const char *lp_template,
- const char *username,
+static bool fillup_pw_field(const char *lp_template,
+ const char *username,
const char *domname,
uid_t uid,
gid_t gid,
- const char *in,
+ const char *in,
fstring out)
{
char *templ;
@@ -40,59 +40,54 @@ static bool fillup_pw_field(const char *lp_template,
if (out == NULL)
return False;
- /* The substitution of %U and %D in the 'template
+ /* The substitution of %U and %D in the 'template
homedir' is done by talloc_sub_specified() below.
If we have an in string (which means the value has already
been set in the nss_info backend), then use that.
Otherwise use the template value passed in. */
if ( in && !strequal(in,"") && lp_security() == SEC_ADS ) {
- templ = talloc_sub_specified(NULL, in,
+ templ = talloc_sub_specified(NULL, in,
username, domname,
uid, gid);
} else {
- templ = talloc_sub_specified(NULL, lp_template,
+ templ = talloc_sub_specified(NULL, lp_template,
username, domname,
- uid, gid);
+ uid, gid);
}
-
+
if (!templ)
return False;
safe_strcpy(out, templ, sizeof(fstring) - 1);
TALLOC_FREE(templ);
-
+
return True;
-
+
}
/* Fill a pwent structure with information we have obtained */
-static bool winbindd_fill_pwent(TALLOC_CTX *ctx, char *dom_name, char *user_name,
+static bool winbindd_fill_pwent(char *dom_name, char *user_name,
DOM_SID *user_sid, DOM_SID *group_sid,
char *full_name, char *homedir, char *shell,
struct winbindd_pw *pw)
{
fstring output_username;
- char *mapped_name = NULL;
- struct winbindd_domain *domain = NULL;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
+
if (!pw || !dom_name || !user_name)
return False;
-
+
/* Resolve the uid number */
- if (!NT_STATUS_IS_OK(idmap_sid_to_uid(dom_name, user_sid,
- &pw->pw_uid))) {
+ if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &pw->pw_uid))) {
DEBUG(1, ("error getting user id for sid %s\n",
sid_string_dbg(user_sid)));
return False;
}
+
+ /* Resolve the gid number */
- /* Resolve the gid number */
-
- if (!NT_STATUS_IS_OK(idmap_sid_to_gid(dom_name, group_sid,
- &pw->pw_gid))) {
+ if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &pw->pw_gid))) {
DEBUG(1, ("error getting group id for sid %s\n",
sid_string_dbg(group_sid)));
return False;
@@ -102,42 +97,21 @@ static bool winbindd_fill_pwent(TALLOC_CTX *ctx, char *dom_name, char *user_name
/* Username */
- domain = find_domain_from_name_noinit(dom_name);
- if (domain) {
- nt_status = normalize_name_map(ctx, domain, user_name,
- &mapped_name);
- } else {
- DEBUG(5,("winbindd_fill_pwent: Failed to find domain for %s. "
- "Disabling name alias support\n", dom_name));
- nt_status = NT_STATUS_NO_SUCH_DOMAIN;
- }
-
- /* Basic removal of whitespace */
- if (NT_STATUS_IS_OK(nt_status)) {
- fill_domain_username(output_username, dom_name, mapped_name, True);
- }
- /* Complete name replacement */
- else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) {
- fstrcpy(output_username, mapped_name);
- }
- /* No change at all */
- else {
- fill_domain_username(output_username, dom_name, user_name, True);
- }
+ fill_domain_username(output_username, dom_name, user_name, True);
safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1);
-
+
/* Full name (gecos) */
-
+
safe_strcpy(pw->pw_gecos, full_name, sizeof(pw->pw_gecos) - 1);
/* Home directory and shell */
-
- if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name,
+
+ if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name,
pw->pw_uid, pw->pw_gid, homedir, pw->pw_dir))
return False;
- if (!fillup_pw_field(lp_template_shell(), user_name, dom_name,
+ if (!fillup_pw_field(lp_template_shell(), user_name, dom_name,
pw->pw_uid, pw->pw_gid, shell, pw->pw_shell))
return False;
@@ -161,7 +135,7 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain,
/* Ensure null termination */
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
- DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid,
state->request.data.sid));
if (!string_to_sid(&sid, state->request.data.sid)) {
@@ -181,7 +155,7 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain,
fstrcpy(state->response.data.user_info.full_name, user_info.full_name);
fstrcpy(state->response.data.user_info.homedir, user_info.homedir);
fstrcpy(state->response.data.user_info.shell, user_info.shell);
- state->response.data.user_info.primary_gid = user_info.primary_gid;
+ state->response.data.user_info.primary_gid = user_info.primary_gid;
if (!sid_peek_check_rid(&domain->sid, &user_info.group_sid,
&state->response.data.user_info.group_rid)) {
DEBUG(1, ("Could not extract group rid out of %s\n",
@@ -203,12 +177,11 @@ struct getpwsid_state {
uid_t uid;
DOM_SID group_sid;
gid_t gid;
- bool username_mapped;
};
static void getpwsid_queryuser_recv(void *private_data, bool success,
const char *acct_name,
- const char *full_name,
+ const char *full_name,
const char *homedir,
const char *shell,
gid_t gid,
@@ -244,10 +217,10 @@ static void winbindd_getpwsid(struct winbindd_cli_state *state,
error:
request_error(state);
}
-
+
static void getpwsid_queryuser_recv(void *private_data, bool success,
const char *acct_name,
- const char *full_name,
+ const char *full_name,
const char *homedir,
const char *shell,
gid_t gid,
@@ -256,8 +229,6 @@ static void getpwsid_queryuser_recv(void *private_data, bool success,
fstring username;
struct getpwsid_state *s =
talloc_get_type_abort(private_data, struct getpwsid_state);
- char *mapped_name;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
if (!success) {
DEBUG(5, ("Could not query domain %s SID %s\n",
@@ -268,59 +239,43 @@ static void getpwsid_queryuser_recv(void *private_data, bool success,
if ( acct_name && *acct_name ) {
fstrcpy( username, acct_name );
- } else {
+ } else {
char *domain_name = NULL;
enum lsa_SidType type;
char *user_name = NULL;
struct winbindd_domain *domain = NULL;
-
+
domain = find_lookup_domain_from_sid(&s->user_sid);
if (domain == NULL) {
DEBUG(5, ("find_lookup_domain_from_sid(%s) failed\n",
sid_string_dbg(&s->user_sid)));
request_error(s->state);
- return;
+ return;
}
winbindd_lookup_name_by_sid(s->state->mem_ctx, domain,
&s->user_sid, &domain_name,
- &user_name, &type );
+ &user_name, &type );
/* If this still fails we ar4e done. Just error out */
if ( !user_name ) {
DEBUG(5,("Could not obtain a name for SID %s\n",
sid_string_dbg(&s->user_sid)));
request_error(s->state);
- return;
+ return;
}
- fstrcpy( username, user_name );
+ fstrcpy( username, user_name );
}
strlower_m( username );
s->username = talloc_strdup(s->state->mem_ctx, username);
- nt_status = normalize_name_map(s->state->mem_ctx, s->domain,
- s->username, &mapped_name);
-
- /* Basic removal of whitespace */
- if (NT_STATUS_IS_OK(nt_status)) {
- s->username = mapped_name;
- s->username_mapped = false;
- }
- /* Complete name replacement */
- else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) {
- s->username = mapped_name;
- s->username_mapped = true;
- }
- /* No change at all */
- else {
- s->username_mapped = false;
- }
-
+ ws_name_replace( s->username, WB_REPLACE_CHAR );
+
s->fullname = talloc_strdup(s->state->mem_ctx, full_name);
s->homedir = talloc_strdup(s->state->mem_ctx, homedir);
s->shell = talloc_strdup(s->state->mem_ctx, shell);
- s->gid = gid;
+ s->gid = gid;
sid_copy(&s->group_sid, &s->domain->sid);
sid_append_rid(&s->group_sid, group_rid);
@@ -373,29 +328,18 @@ static void getpwsid_sid2gid_recv(void *private_data, bool success, gid_t gid)
pw = &s->state->response.data.pw;
pw->pw_uid = s->uid;
pw->pw_gid = s->gid;
-
- /* allow username to be overridden by the alias mapping */
-
- if ( s->username_mapped ) {
- fstrcpy( output_username, s->username );
- } else {
- fill_domain_username(output_username, s->domain->name,
- s->username, True);
- }
-
+ fill_domain_username(output_username, s->domain->name, s->username, True);
safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1);
safe_strcpy(pw->pw_gecos, s->fullname, sizeof(pw->pw_gecos) - 1);
- if (!fillup_pw_field(lp_template_homedir(), s->username,
- s->domain->name, pw->pw_uid, pw->pw_gid,
- s->homedir, pw->pw_dir)) {
+ if (!fillup_pw_field(lp_template_homedir(), s->username, s->domain->name,
+ pw->pw_uid, pw->pw_gid, s->homedir, pw->pw_dir)) {
DEBUG(5, ("Could not compose homedir\n"));
goto failed;
}
- if (!fillup_pw_field(lp_template_shell(), s->username,
- s->domain->name, pw->pw_uid, pw->pw_gid,
- s->shell, pw->pw_shell)) {
+ if (!fillup_pw_field(lp_template_shell(), s->username, s->domain->name,
+ pw->pw_uid, pw->pw_gid, s->shell, pw->pw_shell)) {
DEBUG(5, ("Could not compose shell\n"));
goto failed;
}
@@ -421,39 +365,23 @@ void winbindd_getpwnam(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
fstring domname, username;
- char *mapped_user = NULL;
- char *domuser;
- size_t dusize;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- domuser = state->request.data.username;
- dusize = sizeof(state->request.data.username);
-
- /* Ensure null termination (it's an fstring) */
- domuser[dusize-1] = '\0';
-
- DEBUG(3, ("[%5lu]: getpwnam %s\n",
- (unsigned long)state->pid,
- domuser));
-
- nt_status = normalize_name_unmap(state->mem_ctx, domuser,
- &mapped_user);
+ /* Ensure null termination */
+ state->request.data.username[sizeof(state->request.data.username)-1]='\0';
- /* If we could not convert from an aliased name or a
- normalized name, then just use the original name */
+ DEBUG(3, ("[%5lu]: getpwnam %s\n", (unsigned long)state->pid,
+ state->request.data.username));
- if (!NT_STATUS_IS_OK(nt_status) &&
- !NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
- {
- mapped_user = domuser;
- }
+ ws_name_return( state->request.data.username, WB_REPLACE_CHAR );
- if (!parse_domain_user(mapped_user, domname, username)) {
- DEBUG(5, ("Could not parse domain user: %s\n", domuser));
+ if (!parse_domain_user(state->request.data.username, domname,
+ username)) {
+ DEBUG(5, ("Could not parse domain user: %s\n",
+ state->request.data.username));
request_error(state);
return;
}
-
+
/* Get info for the domain */
domain = find_domain_from_name(domname);
@@ -463,24 +391,22 @@ void winbindd_getpwnam(struct winbindd_cli_state *state)
"Using primary domain\n", domname));
if ( (domain = find_our_domain()) == NULL ) {
DEBUG(0,("Cannot find my primary domain structure!\n"));
- request_error(state);
- return;
- }
+ request_error(state);
+ return;
+ }
}
- if (strequal(domname, lp_workgroup()) &&
- lp_winbind_trusted_domains_only() ) {
- DEBUG(7,("winbindd_getpwnam: My domain -- "
- "rejecting getpwnam() for %s\\%s.\n",
- domname, username));
+ if ( strequal(domname, lp_workgroup()) && lp_winbind_trusted_domains_only() ) {
+ DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n",
+ domname, username));
request_error(state);
return;
- }
+ }
/* Get rid and name type from name. The following costs 1 packet */
winbindd_lookupname_async(state->mem_ctx, domname, username,
- getpwnam_name2sid_recv, WINBINDD_GETPWNAM,
+ getpwnam_name2sid_recv, WINBINDD_GETPWNAM,
state);
}
@@ -489,25 +415,27 @@ static void getpwnam_name2sid_recv(void *private_data, bool success,
{
struct winbindd_cli_state *state =
(struct winbindd_cli_state *)private_data;
- fstring domname, username;
- char *domuser = state->request.data.username;
+ fstring domname, username;
if (!success) {
- DEBUG(5, ("Could not lookup name for user %s\n", domuser));
+ DEBUG(5, ("Could not lookup name for user %s\n",
+ state->request.data.username));
request_error(state);
return;
}
if ((type != SID_NAME_USER) && (type != SID_NAME_COMPUTER)) {
- DEBUG(5, ("%s is not a user\n", domuser));
+ DEBUG(5, ("%s is not a user\n", state->request.data.username));
request_error(state);
return;
}
- if (parse_domain_user(domuser, domname, username)) {
- check_domain_trusted(domname, sid);
+ if ( parse_domain_user(state->request.data.username, domname, username) ) {
+ check_domain_trusted( domname, sid );
}
+
+
winbindd_getpwsid(state, sid);
}
@@ -523,7 +451,7 @@ static void getpwuid_recv(void *private_data, bool success, const char *sid)
request_error(state);
return;
}
-
+
DEBUG(10,("uid2sid_recv: uid %lu has sid %s\n",
(unsigned long)(state->request.data.uid), sid));
@@ -534,16 +462,12 @@ static void getpwuid_recv(void *private_data, bool success, const char *sid)
/* Return a password structure given a uid number */
void winbindd_getpwuid(struct winbindd_cli_state *state)
{
- uid_t uid = state->request.data.uid;
-
- DEBUG(3, ("[%5lu]: getpwuid %lu\n",
- (unsigned long)state->pid,
- (unsigned long)uid));
+ DEBUG(3, ("[%5lu]: getpwuid %lu\n", (unsigned long)state->pid,
+ (unsigned long)state->request.data.uid));
/* always query idmap via the async interface */
- /* if this turns to be too slow we will add here
- * a direct query to the cache */
- winbindd_uid2sid_async(state->mem_ctx, uid, getpwuid_recv, state);
+ /* if this turns to be too slow we will add here a direct query to the cache */
+ winbindd_uid2sid_async(state->mem_ctx, state->request.data.uid, getpwuid_recv, state);
}
/*
@@ -555,53 +479,66 @@ void winbindd_getpwuid(struct winbindd_cli_state *state)
static bool winbindd_setpwent_internal(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
-
+
DEBUG(3, ("[%5lu]: setpwent\n", (unsigned long)state->pid));
-
+
/* Check user has enabled this */
-
+
if (!lp_winbind_enum_users()) {
return False;
}
/* Free old static data if it exists */
-
+
if (state->getpwent_state != NULL) {
free_getent_state(state->getpwent_state);
state->getpwent_state = NULL;
}
+#if 0 /* JERRY */
+ /* add any local users we have */
+
+ if ( (domain_state = (struct getent_state *)malloc(sizeof(struct getent_state))) == NULL )
+ return False;
+
+ ZERO_STRUCTP(domain_state);
+
+ /* Add to list of open domains */
+
+ DLIST_ADD(state->getpwent_state, domain_state);
+#endif
+
/* Create sam pipes for each domain we know about */
-
+
for(domain = domain_list(); domain != NULL; domain = domain->next) {
struct getent_state *domain_state;
-
-
- /* don't add our domaina if we are a PDC or if we
+
+
+ /* don't add our domaina if we are a PDC or if we
are a member of a Samba domain */
-
- if ((IS_DC || lp_winbind_trusted_domains_only())
- && strequal(domain->name, lp_workgroup())) {
+
+ if ( (IS_DC || lp_winbind_trusted_domains_only())
+ && strequal(domain->name, lp_workgroup()) )
+ {
continue;
}
-
+
/* Create a state record for this domain */
-
- domain_state = SMB_MALLOC_P(struct getent_state);
- if (!domain_state) {
+
+ if ((domain_state = SMB_MALLOC_P(struct getent_state)) == NULL) {
DEBUG(0, ("malloc failed\n"));
return False;
}
-
+
ZERO_STRUCTP(domain_state);
fstrcpy(domain_state->domain_name, domain->name);
/* Add to list of open domains */
-
+
DLIST_ADD(state->getpwent_state, domain_state);
}
-
+
state->getpwent_initialized = True;
return True;
}
@@ -621,7 +558,7 @@ void winbindd_endpwent(struct winbindd_cli_state *state)
{
DEBUG(3, ("[%5lu]: endpwent\n", (unsigned long)state->pid));
- free_getent_state(state->getpwent_state);
+ free_getent_state(state->getpwent_state);
state->getpwent_initialized = False;
state->getpwent_state = NULL;
request_ok(state);
@@ -657,23 +594,23 @@ static bool get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx)
SAFE_FREE(ent->sam_entries);
ent->num_sam_entries = 0;
-
+
/* Call query_user_list to get a list of usernames and user rids */
num_entries = 0;
- status = methods->query_user_list(domain, mem_ctx, &num_entries, &info);
-
+ status = methods->query_user_list(domain, mem_ctx, &num_entries,
+ &info);
+
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10,("get_sam_user_entries: "
- "query_user_list failed with %s\n",
- nt_errstr(status)));
+ DEBUG(10,("get_sam_user_entries: query_user_list failed with %s\n",
+ nt_errstr(status) ));
return False;
}
if (num_entries) {
- name_list = SMB_REALLOC_ARRAY(name_list, struct getpwent_user,
- ent->num_sam_entries + num_entries);
+ name_list = SMB_REALLOC_ARRAY(name_list, struct getpwent_user, ent->num_sam_entries + num_entries);
+
if (!name_list) {
DEBUG(0,("get_sam_user_entries realloc failed.\n"));
return False;
@@ -685,40 +622,40 @@ static bool get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx)
if (!info[i].acct_name) {
fstrcpy(name_list[ent->num_sam_entries + i].name, "");
} else {
- fstrcpy(name_list[ent->num_sam_entries + i].name,
- info[i].acct_name);
+ fstrcpy(name_list[ent->num_sam_entries + i].name,
+ info[i].acct_name);
}
if (!info[i].full_name) {
fstrcpy(name_list[ent->num_sam_entries + i].gecos, "");
} else {
- fstrcpy(name_list[ent->num_sam_entries + i].gecos,
- info[i].full_name);
+ fstrcpy(name_list[ent->num_sam_entries + i].gecos,
+ info[i].full_name);
}
if (!info[i].homedir) {
- fstrcpy(name_list[ent->num_sam_entries + i].homedir,"");
+ fstrcpy(name_list[ent->num_sam_entries + i].homedir, "");
} else {
- fstrcpy(name_list[ent->num_sam_entries + i].homedir,
- info[i].homedir);
+ fstrcpy(name_list[ent->num_sam_entries + i].homedir,
+ info[i].homedir);
}
if (!info[i].shell) {
fstrcpy(name_list[ent->num_sam_entries + i].shell, "");
} else {
- fstrcpy(name_list[ent->num_sam_entries + i].shell,
- info[i].shell);
+ fstrcpy(name_list[ent->num_sam_entries + i].shell,
+ info[i].shell);
}
-
-
+
+
/* User and group ids */
sid_copy(&name_list[ent->num_sam_entries+i].user_sid,
&info[i].user_sid);
sid_copy(&name_list[ent->num_sam_entries+i].group_sid,
&info[i].group_sid);
}
-
+
ent->num_sam_entries += num_entries;
-
+
/* Fill in remaining fields */
-
+
ent->sam_entries = name_list;
ent->sam_entry_index = 0;
return ent->num_sam_entries > 0;
@@ -751,20 +688,20 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
request_error(state);
return;
}
-
- user_list = SMB_MALLOC_ARRAY(struct winbindd_pw, num_users);
- if (!user_list) {
+
+ if ((state->response.extra_data.data = SMB_MALLOC_ARRAY(struct winbindd_pw, num_users)) == NULL) {
request_error(state);
return;
}
- /* will be freed by process_request() */
- state->response.extra_data.data = user_list;
- memset(user_list, 0, num_users * sizeof(struct winbindd_pw));
+ memset(state->response.extra_data.data, 0, num_users *
+ sizeof(struct winbindd_pw));
+
+ user_list = (struct winbindd_pw *)state->response.extra_data.data;
if (!state->getpwent_initialized)
winbindd_setpwent_internal(state);
-
+
if (!(ent = state->getpwent_state)) {
request_error(state);
return;
@@ -794,20 +731,19 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
SAFE_FREE(ent);
ent = next_ent;
}
-
+
/* No more domains */
- if (!ent)
+ if (!ent)
break;
}
name_list = (struct getpwent_user *)ent->sam_entries;
/* Lookup user info */
-
+
result = winbindd_fill_pwent(
- state->mem_ctx,
- ent->domain_name,
+ ent->domain_name,
name_list[ent->sam_entry_index].name,
&name_list[ent->sam_entry_index].user_sid,
&name_list[ent->sam_entry_index].group_sid,
@@ -815,21 +751,22 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
name_list[ent->sam_entry_index].homedir,
name_list[ent->sam_entry_index].shell,
&user_list[user_list_ndx]);
-
+
/* Add user to return list */
-
+
if (result) {
-
+
user_list_ndx++;
state->response.data.num_entries++;
- state->response.length += sizeof(struct winbindd_pw);
+ state->response.length +=
+ sizeof(struct winbindd_pw);
} else
DEBUG(1, ("could not lookup domain user %s\n",
name_list[ent->sam_entry_index].name));
ent->sam_entry_index++;
-
+
}
/* Out of domains */
diff --git a/source/winbindd/winbindd_util.c b/source/winbindd/winbindd_util.c
index ebcf625178..cfe91366d5 100644
--- a/source/winbindd/winbindd_util.c
+++ b/source/winbindd/winbindd_util.c
@@ -109,18 +109,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
{
struct winbindd_domain *domain;
const char *alternative_name = NULL;
- char *idmap_config_option;
- const char *param;
- const char **ignored_domains, **dom;
- ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL);
- for (dom=ignored_domains; dom && *dom; dom++) {
- if (gen_fnmatch(*dom, domain_name) == 0) {
- DEBUG(2,("Ignoring domain '%s'\n", domain_name));
- return NULL;
- }
- }
-
/* ignore alt_name if we are not in an AD domain */
if ( (lp_security() == SEC_ADS) && alt_name && *alt_name) {
@@ -189,47 +178,15 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
domain->initialized = False;
domain->online = is_internal_domain(sid);
domain->check_online_timeout = 0;
- domain->dc_probe_pid = (pid_t)-1;
if (sid) {
sid_copy(&domain->sid, sid);
}
-
+
/* Link to domain list */
DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *);
wcache_tdc_add_domain( domain );
- idmap_config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
- domain->name);
- if (idmap_config_option == NULL) {
- DEBUG(0, ("talloc failed, not looking for idmap config\n"));
- goto done;
- }
-
- param = lp_parm_const_string(-1, idmap_config_option, "range", NULL);
-
- DEBUG(10, ("%s : range = %s\n", idmap_config_option,
- param ? param : "not defined"));
-
- if (param != NULL) {
- unsigned low_id, high_id;
- if (sscanf(param, "%u - %u", &low_id, &high_id) != 2) {
- DEBUG(1, ("invalid range syntax in %s: %s\n",
- idmap_config_option, param));
- goto done;
- }
- if (low_id > high_id) {
- DEBUG(1, ("invalid range in %s: %s\n",
- idmap_config_option, param));
- goto done;
- }
- domain->have_idmap_config = true;
- domain->id_range_low = low_id;
- domain->id_range_high = high_id;
- }
-
-done:
-
DEBUG(2,("Added domain %s %s %s\n",
domain->name, domain->alt_name,
&domain->sid?sid_string_dbg(&domain->sid):""));
@@ -445,10 +402,6 @@ static void rescan_forest_root_trusts( void )
&dom_list[i].sid );
}
- if (d == NULL) {
- continue;
- }
-
DEBUG(10,("rescan_forest_root_trusts: Following trust path "
"for domain tree root %s (%s)\n",
d->name, d->alt_name ));
@@ -513,10 +466,6 @@ static void rescan_forest_trusts( void )
&cache_methods,
&dom_list[i].sid );
}
-
- if (d == NULL) {
- continue;
- }
DEBUG(10,("Following trust path for domain %s (%s)\n",
d->name, d->alt_name ));
@@ -1075,12 +1024,13 @@ void free_getent_state(struct getent_state *state)
temp = state;
while(temp != NULL) {
- struct getent_state *next = temp->next;
+ struct getent_state *next;
/* Free sam entries then list entry */
SAFE_FREE(state->sam_entries);
DLIST_REMOVE(state, state);
+ next = temp->next;
SAFE_FREE(temp);
temp = next;
@@ -1394,107 +1344,34 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
We use this to remove spaces from user and group names
********************************************************************/
-NTSTATUS normalize_name_map(TALLOC_CTX *mem_ctx,
- struct winbindd_domain *domain,
- char *name,
- char **normalized)
+void ws_name_replace( char *name, char replace )
{
- NTSTATUS nt_status;
-
- if (!name || !normalized) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!lp_winbind_normalize_names()) {
- return NT_STATUS_PROCEDURE_NOT_FOUND;
- }
-
- /* Alias support and whitespace replacement are mutually
- exclusive */
-
- nt_status = resolve_username_to_alias(mem_ctx, domain,
- name, normalized );
- if (NT_STATUS_IS_OK(nt_status)) {
- /* special return code to let the caller know we
- mapped to an alias */
- return NT_STATUS_FILE_RENAMED;
- }
-
- /* check for an unreachable domain */
-
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- DEBUG(5,("normalize_name_map: Setting domain %s offline\n",
- domain->name));
- set_domain_offline(domain);
- return nt_status;
- }
-
- /* deal with whitespace */
-
- *normalized = talloc_strdup(mem_ctx, name);
- if (!(*normalized)) {
- return NT_STATUS_NO_MEMORY;
- }
+ char replace_char[2] = { 0x0, 0x0 };
+
+ if ( !lp_winbind_normalize_names() || (replace == '\0') )
+ return;
- all_string_sub( *normalized, " ", "_", 0 );
+ replace_char[0] = replace;
+ all_string_sub( name, " ", replace_char, 0 );
- return NT_STATUS_OK;
+ return;
}
/*********************************************************************
- We use this to do the inverse of normalize_name_map()
+ We use this to do the inverse of ws_name_replace()
********************************************************************/
-NTSTATUS normalize_name_unmap(TALLOC_CTX *mem_ctx,
- char *name,
- char **normalized)
+void ws_name_return( char *name, char replace )
{
- NTSTATUS nt_status;
- struct winbindd_domain *domain = find_our_domain();
-
- if (!name || !normalized) {
- return NT_STATUS_INVALID_PARAMETER;
- }
+ char replace_char[2] = { 0x0, 0x0 };
+
+ if ( !lp_winbind_normalize_names() || (replace == '\0') )
+ return;
- if (!lp_winbind_normalize_names()) {
- return NT_STATUS_PROCEDURE_NOT_FOUND;
- }
-
- /* Alias support and whitespace replacement are mutally
- exclusive */
-
- /* When mapping from an alias to a username, we don't know the
- domain. But we only need a domain structure to cache
- a successful lookup , so just our own domain structure for
- the seqnum. */
+ replace_char[0] = replace;
+ all_string_sub( name, replace_char, " ", 0 );
- nt_status = resolve_alias_to_username(mem_ctx, domain,
- name, normalized);
- if (NT_STATUS_IS_OK(nt_status)) {
- /* Special return code to let the caller know we mapped
- from an alias */
- return NT_STATUS_FILE_RENAMED;
- }
-
- /* check for an unreachable domain */
-
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
- DEBUG(5,("normalize_name_unmap: Setting domain %s offline\n",
- domain->name));
- set_domain_offline(domain);
- return nt_status;
- }
-
- /* deal with whitespace */
-
- *normalized = talloc_strdup(mem_ctx, name);
- if (!(*normalized)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- all_string_sub(*normalized, "_", " ", 0);
-
- return NT_STATUS_OK;
+ return;
}
/*********************************************************************
@@ -1658,15 +1535,3 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain)
}
#endif /* HAVE_KRB5_LOCATE_PLUGIN_H */
-
-void set_auth_errors(struct winbindd_response *resp, NTSTATUS result)
-{
- resp->data.auth.nt_status = NT_STATUS_V(result);
- fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result));
-
- /* we might have given a more useful error above */
- if (*resp->data.auth.error_string == '\0')
- fstrcpy(resp->data.auth.error_string,
- get_friendly_nt_error_msg(result));
- resp->data.auth.pam_error = nt_status_to_pam(result);
-}