Hi Jelmer, Hi Andrew, Hi Stefan I've started to code up some functions to parse the lp_sam_backend list and create a sam_context from it. In contrast to the current implementation, these functions can take a domain name per backend and pass it down to the apropriate sam_init(). To create a maximum of flexibility, the domain name is prefixed with "D-" and the module_params are prefixed with "O-". This allows to leave either of the two away or swapp them arround.
The smb.conf entery could look something like this: sam backend = sam_moduleA:D-domainA:O-options_for_sam_moduleA sam_moduleB:O-options_for_sam_moduleB:sup_options:D-domainB or sam backend = sam_moduleA Currently the entire checking for correctnes is still missing apart from many other points. In addition the style is still terrible, but I wanted to know if this is the right direction before I continue to put effort into it. So any comments are welcome. Kai typedef struct sam_backend_entry { char *module_name; char *module_params; char *domain_name; DOM_SID *domain_sid; } SAM_BACKEND_ENTRY; static NTSTATUS make_backend_entry(SAM_BACKEND_ENTRY *backend_entry, char *sam_backend_string) { char *tmp = NULL; char *tmp_string = sam_backend_string; BOOL allow_intermediate_colon = False; if (sam_backend_string == NULL) return NT_STATUS_INVALID_PARAMETER; backend_entry->module_name = sam_backend_string; while ((tmp = strchr(tmp_string,':')) != NULL) { if (tmp[2] == '-') { switch (tmp[1]) { case 'D': { *tmp = 0; backend_entry->domain_name = tmp + 3; allow_intermediate_colon = False; break; } case 'O': { *tmp = 0; backend_entry->module_params = tmp + 3; allow_intermediate_colon = True; break; } default: if (!allow_intermediate_colon) { DEBUG(2,("make_backend_entry: Error\n")); return NT_STATUS_INVALID_PARAMETER; } } } else if (!allow_intermediate_colon) { DEBUG(2,("make_backend_entry: Error\n")); return NT_STATUS_INVALID_PARAMETER; } tmp_string = tmp + 1; } if (backend_entry->domain_name == NULL) { DEBUG(5,("make_backend_entry: no domain was specified for sam module %s. Useing default domain %s\n", backend_entry->module_name, lp_workgroup())); backend_entry->domain_name = lp_workgroup(); } if (!secrets_fetch_domain_sid(backend_entry->domain_name,backend_entry->domain_ sid)) { DEBUG(2,("make_backend_entry: There is no SID stored for domain %s. Creating a new one.\n", backend_entry->domain_name)); /* FIXME */ } return NT_STATUS_OK; } static NTSTATUS make_sam_methods_backend_entry(SAM_METHODS **methods, SAM_CONTEXT *context, SAM_BACKEND_ENTRY *sam_backend_entry) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; int i; DEBUG(5,("Attempting to find sam backend %s\n", backend_entry->module_name)); for (i = 0; builtin_sam_init_functions[i].module_name; i++) { if (strequal(builtin_sam_init_functions[i].module_name, backend_entry->module_name)) { DEBUG(5,("Found sam backend %s (at pos %d)\n", backend_entry->module_name, i)); nt_status = builtin_sam_init_functions[i].init(context, methods, backend_entry->domain_sid, backend_entry->module_params); if (NT_STATUS_IS_OK(nt_status)) { DEBUG(5,("sam backend %s has a valid init\n", backend_entry->module_name)); } else { DEBUG(2,("sam backend %s did not correctly init (error was %s)\n", backend_entry->module_name, nt_errstr(nt_status))); } return nt_status; break; /* unreached */ } } DEBUG(2,("could not find backend %s\n", backend_entry->module_name)); return NT_STATUS_INVALID_PARAMETER; } NTSTATUS make_sam_context_from_conf(SAM_CONTEXT **context) { int i = 0; SAM_METHODS *curmethods, *tmpmethods; char **sam_backends_param = lp_sam_backend(); int nBackends = 0; SAM_BACKEND_ENTRY *backends = NULL; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; DEBUG(5,("make_sam_context_from_conf: %d\n", __LINE__)); if (!NT_STATUS_IS_OK(nt_status = make_sam_context(context))) { DEBUG(4,("make_sam_context failed\n")); return nt_status; } while (sam_backends_param[nBackends]) nBackends++; DEBUG(6,("There are %d domains listed with there backends\n", nBackends)); backends = malloc(sizeof(SAM_BACKEND_ENTRY)*nBackends); ZERO_STRUCT(backends); for (i = 0; i < nBackends; i++) { if (!NT_STATUS_IS_OK(nt_status = make_backend_entry(&backends[i], sam_backends_param[i]))) { DEBUG(4,("make_backend_entry failed\n")); SAFE_FREE(backends); free_sam_context(context); return nt_status; } } /* FIXME check the returned values and correct them if neccessary */ for (i = 0; i < nBackends; i++) { if (!NT_STATUS_IS_OK(nt_status = make_sam_methods_backend_entry(&curmethods, *context, &backends[i]))) { DEBUG(4,("make_sam_methods_backend_entry failed\n")); SAFE_FREE(backends); free_sam_context(context); return nt_status; } curmethods->parent = *context; DLIST_ADD_END((*context)->methods, curmethods, tmpmethods); } SAFE_FREE(backends); return NT_STATUS_OK; }