domain->sequence_number = DOM_SEQUENCE_NONE;
domain->last_seq_check = 0;
domain->initialized = False;
- domain->online = False;
+ domain->online = is_internal_domain(sid);
+ domain->check_online_timeout = 0;
if (sid) {
sid_copy(&domain->sid, sid);
}
return;
}
- p = response->extra_data.data;
+ p = (char *)response->extra_data.data;
while ((p != NULL) && (*p != '\0')) {
char *q, *sidstr, *alt_name;
if ((request == NULL) || (response == NULL) || (state == NULL)) {
DEBUG(0, ("talloc failed\n"));
+ TALLOC_FREE(mem_ctx);
continuation(private_data, False);
return WINBINDD_ERROR;
}
state->continuation = continuation;
state->private_data = private_data;
- if (domain->primary) {
+ if (IS_DC || domain->primary) {
/* The primary domain has to find the DC name itself */
request->cmd = WINBINDD_INIT_CONNECTION;
fstrcpy(request->domain_name, domain->name);
enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
- struct in_addr ipaddr;
-
/* Ensure null termination */
state->request.domain_name
[sizeof(state->request.domain_name)-1]='\0';
fstrcpy(domain->dcname, state->request.data.init_conn.dcname);
}
- if (strlen(domain->dcname) > 0) {
- if (!resolve_name(domain->dcname, &ipaddr, 0x20)) {
- DEBUG(2, ("Could not resolve DC name %s for domain %s\n",
- domain->dcname, domain->name));
- return WINBINDD_ERROR;
- }
-
- domain->dcaddr.sin_family = PF_INET;
- putip((char *)&(domain->dcaddr.sin_addr), (char *)&ipaddr);
- domain->dcaddr.sin_port = 0;
- }
-
- set_dc_type_and_flags(domain);
+ init_dc_connection(domain);
if (!domain->initialized) {
- DEBUG(1, ("Could not initialize domain %s\n",
- state->request.domain_name));
- return WINBINDD_ERROR;
+ /* If we return error here we can't do any cached authentication,
+ but we may be in disconnected mode and can't initialize correctly.
+ Do what the previous code did and just return without initialization,
+ once we go online we'll re-initialize.
+ */
+ DEBUG(5, ("winbindd_dual_init_connection: %s returning without initialization "
+ "online = %d\n", domain->name, (int)domain->online ));
}
fstrcpy(state->response.data.domain_info.name, domain->name);
return NULL;
if (!domain->initialized)
- set_dc_type_and_flags(domain);
+ init_dc_connection(domain);
return domain;
}
return NULL;
if (!domain->initialized)
- set_dc_type_and_flags(domain);
+ init_dc_connection(domain);
return domain;
}
struct winbindd_domain *domain,
const char *domain_name,
const char *name, DOM_SID *sid,
- enum SID_NAME_USE *type)
+ enum lsa_SidType *type)
{
NTSTATUS result;
DOM_SID *sid,
fstring dom_name,
fstring name,
- enum SID_NAME_USE *type)
+ enum lsa_SidType *type)
{
char *names;
char *dom_names;
/* Is this a domain which we may assume no DOMAIN\ prefix? */
-static BOOL assume_domain(const char *domain) {
- if ((lp_winbind_use_default_domain()
- || lp_winbind_trusted_domains_only()) &&
- strequal(lp_workgroup(), domain))
- return True;
+static BOOL assume_domain(const char *domain)
+{
+ /* never assume the domain on a standalone server */
+
+ if ( lp_server_role() == ROLE_STANDALONE )
+ return False;
+
+ /* domain member servers may possibly assume for the domain name */
- if (strequal(get_global_sam_name(), domain))
+ if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
+ if ( !strequal(lp_workgroup(), domain) )
+ return False;
+
+ if ( lp_winbind_use_default_domain() || lp_winbind_trusted_domains_only() )
+ return True;
+ }
+
+ /* only left with a domain controller */
+
+ if ( strequal(get_global_sam_name(), domain) ) {
return True;
+ }
return False;
}
if ( !p ) {
fstrcpy(user, domuser);
-
+
if ( assume_domain(lp_workgroup())) {
fstrcpy(domain, lp_workgroup());
} else {
return ((*domain != NULL) && (*user != NULL));
}
+/* Ensure an incoming username from NSS is fully qualified. Replace the
+ incoming fstring with DOMAIN <separator> user. Returns the same
+ values as parse_domain_user() but also replaces the incoming username.
+ Used to ensure all names are fully qualified within winbindd.
+ Used by the NSS protocols of auth, chauthtok, logoff and ccache_ntlm_auth.
+ The protocol definitions of auth_crap, chng_pswd_auth_crap
+ really should be changed to use this instead of doing things
+ by hand. JRA. */
+
+BOOL canonicalize_username(fstring username_inout, fstring domain, fstring user)
+{
+ if (!parse_domain_user(username_inout, domain, user)) {
+ return False;
+ }
+ slprintf(username_inout, sizeof(fstring) - 1, "%s%c%s",
+ domain, *lp_winbind_separator(),
+ user);
+ return True;
+}
+
/*
Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and
'winbind separator' options.
Also, if omit DOMAIN if 'winbind trusted domains only = true', as the
username is then unqualified in unix
-
+
+ We always canonicalize as UPPERCASE DOMAIN, lowercase username.
*/
void fill_domain_username(fstring name, const char *domain, const char *user, BOOL can_assume)
{
strlower_m(tmp_user);
if (can_assume && assume_domain(domain)) {
- strlcpy(name, user, sizeof(fstring));
+ strlcpy(name, tmp_user, sizeof(fstring));
} else {
slprintf(name, sizeof(fstring) - 1, "%s%c%s",
domain, *lp_winbind_separator(),
_num_clients--;
}
-/* Demote a client to be the last in the list */
-
-void winbindd_demote_client(struct winbindd_cli_state *cli)
-{
- struct winbindd_cli_state *tmp;
- DLIST_DEMOTE(_client_list, cli, tmp);
-}
-
/* Close all open clients */
void winbindd_kill_all_clients(void)
return False;
}
- bigendianheader = (idmap_tdb->flags & TDB_BIGENDIAN) ? True : False;
+ bigendianheader = (tdb_get_flags(idmap_tdb) & TDB_BIGENDIAN) ? True : False;
vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION");
pstrcpy(backup_name, idmap_name);
pstrcat(backup_name, ".bak");
- if (backup_tdb(idmap_name, backup_name) != 0) {
+ if (backup_tdb(idmap_name, backup_name, 0) != 0) {
DEBUG(0, ("Could not backup idmap database\n"));
return False;
}
return idmap_convert(idmap_name);
}
-void winbindd_flush_nscd_cache(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)
{
-#ifdef HAVE_NSCD_FLUSH_CACHE
+ NET_USER_INFO_3 *info3 = NULL;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
+ int i;
+ size_t num_groups = 0;
+ DOM_SID group_sid, primary_group;
+
+ DEBUG(3,(": lookup_usergroups_cached\n"));
+
+ *user_sids = NULL;
+ num_groups = 0;
+ *p_num_groups = 0;
+
+ info3 = netsamlogon_cache_get(mem_ctx, user_sid);
- /* Flush nscd caches to get accurate new information */
- int ret = nscd_flush_cache("passwd");
- if (ret) {
- DEBUG(5,("failed to flush nscd cache for 'passwd' service: %s\n",
- strerror(ret)));
+ if (info3 == NULL) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- ret = nscd_flush_cache("group");
- if (ret) {
- DEBUG(5,("failed to flush nscd cache for 'group' service: %s\n",
- strerror(ret)));
+ if (info3->num_groups == 0) {
+ SAFE_FREE(info3);
+ return NT_STATUS_UNSUCCESSFUL;
}
-#else
- return;
-#endif
-}
+
+ /* always add the primary group to the sid array */
+ sid_compose(&primary_group, &info3->dom_sid.sid, info3->user_rid);
+
+ if (!add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups)) {
+ SAFE_FREE(info3);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<info3->num_groups; i++) {
+ sid_copy(&group_sid, &info3->dom_sid.sid);
+ sid_append_rid(&group_sid, info3->gids[i].g_rid);
+ if (!add_sid_to_array(mem_ctx, &group_sid, user_sids,
+ &num_groups)) {
+ SAFE_FREE(info3);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ SAFE_FREE(info3);
+ *p_num_groups = num_groups;
+ status = (user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
+
+ DEBUG(3,(": lookup_usergroups_cached succeeded\n"));
+
+ return status;
+}