diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c index b3a3d39..e332ae0 100644 --- a/source/auth/auth_util.c +++ b/source/auth/auth_util.c @@ -546,6 +546,30 @@ static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx) } /*************************************************************************** + Is the incoming username our own machine account ? + If so, the connection is almost certainly from winbindd. +***************************************************************************/ + +static BOOL is_our_machine_account(const char *username) +{ + BOOL ret; + char *truncname = NULL; + size_t ulen = strlen(username); + + if (ulen == 0 || username[ulen-1] != '$') { + return False; + } + truncname = SMB_STRDUP(username); + if (!truncname) { + return False; + } + truncname[ulen-1] = '\0'; + ret = strequal(truncname, global_myname()); + SAFE_FREE(truncname); + return ret; +} + +/*************************************************************************** Make (and fill) a user_info struct from a struct samu ***************************************************************************/ @@ -559,11 +583,11 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, int i; size_t num_gids; DOM_SID unix_group_sid; - + const char *username = pdb_get_username(sampass); - if ( !(pwd = getpwnam_alloc(NULL, pdb_get_username(sampass))) ) { + if ( !(pwd = getpwnam_alloc(NULL, username)) ) { DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n", - pdb_get_username(sampass))); + username)); return NT_STATUS_NO_SUCH_USER; } @@ -579,9 +603,25 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, TALLOC_FREE(pwd); - status = pdb_enum_group_memberships(result, sampass, + if (IS_DC && is_our_machine_account(username)) { + /* + * Ensure for a connection from our own + * machine account (from winbindd on a DC) + * there are no supplementary groups. + * Prevents loops in calling gid_to_sid(). + */ + result->sids = NULL; + gids = NULL; + result->num_sids = 0; + + DEBUG(10, ("make_server_info_sam: our machine account %s " + "setting supplementary group list empty.\n", + username)); + } else { + status = pdb_enum_group_memberships(result, sampass, &result->sids, &gids, &result->num_sids); + } if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("pdb_enum_group_memberships failed: %s\n", diff --git a/source/passdb/lookup_sid.c b/source/passdb/lookup_sid.c index d1390fd..4713bc3 100644 --- a/source/passdb/lookup_sid.c +++ b/source/passdb/lookup_sid.c @@ -1333,6 +1333,22 @@ void uid_to_sid(DOM_SID *psid, uid_t uid) if (fetch_sid_from_uid_cache(psid, uid)) return; + if (IS_DC) { + /* + * We're authoritative, ask ourselves first. + */ + BOOL ret; + + become_root(); + ret = pdb_uid_to_sid(uid, psid); + unbecome_root(); + if (ret) { + goto done; + } + + /* Fall through to asking winbindd. */ + } + if (!winbind_uid_to_sid(psid, uid)) { if (!winbind_ping()) { legacy_uid_to_sid(psid, uid); @@ -1343,7 +1359,9 @@ void uid_to_sid(DOM_SID *psid, uid_t uid) uid)); return; } - + + done: + DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid, sid_string_static(psid))); @@ -1358,10 +1376,26 @@ void uid_to_sid(DOM_SID *psid, uid_t uid) void gid_to_sid(DOM_SID *psid, gid_t gid) { ZERO_STRUCTP(psid); - + if (fetch_sid_from_gid_cache(psid, gid)) return; + if (IS_DC) { + /* + * We're authoritative, ask ourselves first. + */ + BOOL ret; + + become_root(); + ret = pdb_gid_to_sid(gid, psid); + unbecome_root(); + if (ret) { + goto done; + } + + /* Fall through to asking winbindd. */ + } + if (!winbind_gid_to_sid(psid, gid)) { if (!winbind_ping()) { legacy_gid_to_sid(psid, gid); @@ -1373,9 +1407,11 @@ void gid_to_sid(DOM_SID *psid, gid_t gid) return; } + done: + DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid, sid_string_static(psid))); - + store_gid_sid_cache(psid, gid); return; }