uint32_t session_info_flags,
struct auth_session_info **session_info)
{
+ enum server_role server_role = lp_server_role();
TALLOC_CTX *tmp_ctx;
struct PAC_LOGON_INFO *logon_info = NULL;
struct netr_SamInfo3 *info3_copy = NULL;
char *ntuser;
char *ntdomain;
char *username;
- char *rhost;
+ const char *rhost;
struct passwd *pw;
NTSTATUS status;
- int rc;
tmp_ctx = talloc_new(mem_ctx);
if (!tmp_ctx) {
return NT_STATUS_NO_MEMORY;
}
- if (pac_blob) {
-#ifdef HAVE_KRB5
- struct wbcAuthUserParams params = {};
+ if (tsocket_address_is_inet(remote_address, "ip")) {
+ rhost = tsocket_address_inet_addr_string(
+ remote_address, tmp_ctx);
+ if (rhost == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ } else {
+ rhost = "127.0.0.1";
+ }
+
+ if (server_role != ROLE_STANDALONE) {
+ struct wbcAuthUserParams params = { 0 };
struct wbcAuthUserInfo *info = NULL;
struct wbcAuthErrorInfo *err = NULL;
+ struct auth_serversupplied_info *server_info = NULL;
+ char *original_user_name = NULL;
+ char *p = NULL;
wbcErr wbc_err;
+ if (pac_blob == NULL) {
+ /*
+ * This should already be catched at the main
+ * gensec layer, but better check twice
+ */
+ status = NT_STATUS_INTERNAL_ERROR;
+ goto done;
+ }
+
/*
* Let winbind decode the PAC.
* This will also store the user
* data in the netsamlogon cache.
*
- * We need to do this *before* we
- * call get_user_from_kerberos_info()
- * as that does a user lookup that
- * expects info in the netsamlogon cache.
- *
- * See BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259
+ * This used to be a cache prime
+ * optimization, but now we delegate
+ * all logic to winbindd, as we require
+ * winbindd as domain member anyway.
*/
params.level = WBC_AUTH_USER_LEVEL_PAC;
params.password.pac.data = pac_blob->data;
params.password.pac.length = pac_blob->length;
+ /* we are contacting the privileged pipe */
become_root();
wbc_err = wbcAuthenticateUserEx(¶ms, &info, &err);
unbecome_root();
*/
switch (wbc_err) {
- case WBC_ERR_WINBIND_NOT_AVAILABLE:
case WBC_ERR_SUCCESS:
break;
+ case WBC_ERR_WINBIND_NOT_AVAILABLE:
+ status = NT_STATUS_NO_LOGON_SERVERS;
+ DBG_ERR("winbindd not running - "
+ "but required as domain member: %s\n",
+ nt_errstr(status));
+ goto done;
case WBC_ERR_AUTH_ERROR:
status = NT_STATUS(err->nt_status);
wbcFreeMemory(err);
goto done;
+ case WBC_ERR_NO_MEMORY:
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
default:
status = NT_STATUS_LOGON_FAILURE;
goto done;
}
+ status = make_server_info_wbcAuthUserInfo(tmp_ctx,
+ info->account_name,
+ info->domain_name,
+ info, &server_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n",
+ nt_errstr(status)));
+ goto done;
+ }
+
+ /* We skip doing this step if the caller asked us not to */
+ if (!(server_info->guest)) {
+ const char *unix_username = server_info->unix_name;
+
+ /* We might not be root if we are an RPC call */
+ become_root();
+ status = smb_pam_accountcheck(unix_username, rhost);
+ unbecome_root();
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] "
+ "FAILED with error %s\n",
+ unix_username, nt_errstr(status)));
+ goto done;
+ }
+
+ DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] "
+ "succeeded\n", unix_username));
+ }
+
+ DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
+
+ p = strchr_m(princ_name, '@');
+ if (!p) {
+ DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
+ princ_name));
+ status = NT_STATUS_LOGON_FAILURE;
+ goto done;
+ }
+
+ original_user_name = talloc_strndup(tmp_ctx, princ_name, p - princ_name);
+ if (original_user_name == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ status = create_local_token(mem_ctx,
+ server_info,
+ NULL,
+ original_user_name,
+ session_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("create_local_token failed: %s\n",
+ nt_errstr(status)));
+ goto done;
+ }
+
+ goto session_info_ready;
+ }
+
+ /* This is the standalone legacy code path */
+
+ if (pac_blob != NULL) {
+#ifdef HAVE_KRB5
status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL,
NULL, NULL, 0, &logon_info);
#else
}
}
- rc = get_remote_hostname(remote_address,
- &rhost,
- tmp_ctx);
- if (rc < 0) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
- if (strequal(rhost, "UNKNOWN")) {
- rhost = tsocket_address_inet_addr_string(remote_address,
- tmp_ctx);
- if (rhost == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
- }
-
status = get_user_from_kerberos_info(tmp_ctx, rhost,
princ_name, logon_info,
&is_mapped, &is_guest,
goto done;
}
+session_info_ready:
+
/* setup the string used by %U */
set_current_user_info((*session_info)->unix_info->sanitized_username,
(*session_info)->unix_info->unix_name,
lp_load_with_shares(get_dyn_CONFIGFILE());
DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
- ntuser, ntdomain, rhost));
+ (*session_info)->info->account_name,
+ (*session_info)->info->domain_name,
+ rhost));
status = NT_STATUS_OK;