int set_cookie_header_cb (const char *hdr, void *closure) { struct url *u = (struct url *)closure; struct cookie *cookie; cookies_now = time (NULL); cookie = parse_set_cookies (hdr); if (!cookie) goto out; /* Sanitize parts of cookie. */ if (!cookie->domain) cookie->domain = xstrdup (u->host); else { if (!check_domain_match (cookie->domain, u->host)) { DEBUGP (("Attempt to fake the domain: %s, %s\n", cookie->domain, u->host)); goto out; } } if (!cookie->path) cookie->path = xstrdup (u->path); else { if (!check_path_match (cookie->path, u->path)) { DEBUGP (("Attempt to fake the path: %s, %s\n", cookie->path, u->path)); goto out; } } cookie->port = u->port; if (cookie->discard_requested) { discard_matching_cookie (cookie); delete_cookie (cookie); return 1; } store_cookie (cookie); return 1; out: if (cookie) delete_cookie (cookie); return 1; }
NTSTATUS auth_check_ntlm_password(const struct auth_context *auth_context, const struct auth_usersupplied_info *user_info, struct auth_serversupplied_info **server_info) { /* if all the modules say 'not for me' this is reasonable */ NTSTATUS nt_status = NT_STATUS_NO_SUCH_USER; const char *unix_username; auth_methods *auth_method; TALLOC_CTX *mem_ctx; if (!user_info || !auth_context || !server_info) return NT_STATUS_LOGON_FAILURE; DEBUG(3, ("check_ntlm_password: Checking password for unmapped user [%s]\\[%s]@[%s] with the new password interface\n", user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name)); DEBUG(3, ("check_ntlm_password: mapped user is: [%s]\\[%s]@[%s]\n", user_info->mapped.domain_name, user_info->mapped.account_name, user_info->workstation_name)); if (auth_context->challenge.length != 8) { DEBUG(0, ("check_ntlm_password: Invalid challenge stored for this auth context - cannot continue\n")); return NT_STATUS_LOGON_FAILURE; } if (auth_context->challenge_set_by) DEBUG(10, ("check_ntlm_password: auth_context challenge created by %s\n", auth_context->challenge_set_by)); DEBUG(10, ("challenge is: \n")); dump_data(5, auth_context->challenge.data, auth_context->challenge.length); #ifdef DEBUG_PASSWORD DEBUG(100, ("user_info has passwords of length %d and %d\n", (int)user_info->password.response.lanman.length, (int)user_info->password.response.nt.length)); DEBUG(100, ("lm:\n")); dump_data(100, user_info->password.response.lanman.data, user_info->password.response.lanman.length); DEBUG(100, ("nt:\n")); dump_data(100, user_info->password.response.nt.data, user_info->password.response.nt.length); #endif /* This needs to be sorted: If it doesn't match, what should we do? */ if (!check_domain_match(user_info->client.account_name, user_info->mapped.domain_name)) return NT_STATUS_LOGON_FAILURE; for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next) { NTSTATUS result; mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name, user_info->mapped.domain_name, user_info->client.account_name); result = auth_method->auth(auth_context, auth_method->private_data, mem_ctx, user_info, server_info); /* check if the module did anything */ if ( NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ) { DEBUG(10,("check_ntlm_password: %s had nothing to say\n", auth_method->name)); talloc_destroy(mem_ctx); continue; } nt_status = result; if (NT_STATUS_IS_OK(nt_status)) { DEBUG(3, ("check_ntlm_password: %s authentication for user [%s] succeeded\n", auth_method->name, user_info->client.account_name)); } else { DEBUG(5, ("check_ntlm_password: %s authentication for user [%s] FAILED with error %s\n", auth_method->name, user_info->client.account_name, nt_errstr(nt_status))); } talloc_destroy(mem_ctx); if ( NT_STATUS_IS_OK(nt_status)) { break; } } /* successful authentication */ if (NT_STATUS_IS_OK(nt_status)) { unix_username = (*server_info)->unix_name; if (!(*server_info)->guest) { const char *rhost; if (tsocket_address_is_inet(user_info->remote_host, "ip")) { rhost = tsocket_address_inet_addr_string(user_info->remote_host, talloc_tos()); if (rhost == NULL) { return NT_STATUS_NO_MEMORY; } } else { rhost = "127.0.0.1"; } /* We might not be root if we are an RPC call */ become_root(); nt_status = smb_pam_accountcheck(unix_username, rhost); unbecome_root(); if (NT_STATUS_IS_OK(nt_status)) { DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] succeeded\n", unix_username)); } else { DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] FAILED with error %s\n", unix_username, nt_errstr(nt_status))); } } if (NT_STATUS_IS_OK(nt_status)) { DEBUG((*server_info)->guest ? 5 : 2, ("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n", (*server_info)->guest ? "guest " : "", user_info->client.account_name, user_info->mapped.account_name, unix_username)); } return nt_status; } /* failed authentication; check for guest lapping */ DEBUG(2, ("check_ntlm_password: Authentication for user [%s] -> [%s] FAILED with error %s\n", user_info->client.account_name, user_info->mapped.account_name, nt_errstr(nt_status))); ZERO_STRUCTP(server_info); return nt_status; }
/** * Check a user's Plaintext, LM or NTLM password. * * Check a user's password, as given in the user_info struct and return various * interesting details in the server_info struct. * * This function does NOT need to be in a become_root()/unbecome_root() pair * as it makes the calls itself when needed. * * The return value takes precedence over the contents of the server_info * struct. When the return is other than NT_STATUS_OK the contents * of that structure is undefined. * * @param user_info Contains the user supplied components, including the passwords. * Must be created with make_user_info() or one of its wrappers. * * @param auth_context Supplies the challenges and some other data. * Must be created with make_auth_context(), and the challenges should be * filled in, either at creation or by calling the challenge geneation * function auth_get_challenge(). * * @param pserver_info If successful, contains information about the authentication, * including a struct samu struct describing the user. * * @param pauthoritative Indicates if the result should be treated as final * result. * * @return An NTSTATUS with NT_STATUS_OK or an appropriate error. * **/ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx, const struct auth_context *auth_context, const struct auth_usersupplied_info *user_info, struct auth_serversupplied_info **pserver_info, uint8_t *pauthoritative) { TALLOC_CTX *frame; const char *auth_method_name = ""; /* if all the modules say 'not for me' this is reasonable */ NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED; const char *unix_username; auth_methods *auth_method; struct auth_serversupplied_info *server_info = NULL; struct dom_sid sid = {0}; if (user_info == NULL || auth_context == NULL || pserver_info == NULL) { return NT_STATUS_LOGON_FAILURE; } frame = talloc_stackframe(); *pauthoritative = 1; DEBUG(3, ("check_ntlm_password: Checking password for unmapped user [%s]\\[%s]@[%s] with the new password interface\n", user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name)); DEBUG(3, ("check_ntlm_password: mapped user is: [%s]\\[%s]@[%s]\n", user_info->mapped.domain_name, user_info->mapped.account_name, user_info->workstation_name)); if (auth_context->challenge.length != 8) { DEBUG(0, ("check_ntlm_password: Invalid challenge stored for this auth context - cannot continue\n")); nt_status = NT_STATUS_LOGON_FAILURE; goto fail; } if (auth_context->challenge_set_by) DEBUG(10, ("check_ntlm_password: auth_context challenge created by %s\n", auth_context->challenge_set_by)); DEBUG(10, ("challenge is: \n")); dump_data(5, auth_context->challenge.data, auth_context->challenge.length); #ifdef DEBUG_PASSWORD DEBUG(100, ("user_info has passwords of length %d and %d\n", (int)user_info->password.response.lanman.length, (int)user_info->password.response.nt.length)); DEBUG(100, ("lm:\n")); dump_data(100, user_info->password.response.lanman.data, user_info->password.response.lanman.length); DEBUG(100, ("nt:\n")); dump_data(100, user_info->password.response.nt.data, user_info->password.response.nt.length); #endif /* This needs to be sorted: If it doesn't match, what should we do? */ if (!check_domain_match(user_info->client.account_name, user_info->mapped.domain_name)) { nt_status = NT_STATUS_LOGON_FAILURE; goto fail; } for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next) { auth_method_name = auth_method->name; nt_status = auth_method->auth(auth_context, auth_method->private_data, talloc_tos(), user_info, &server_info); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { break; } DBG_DEBUG("%s had nothing to say\n", auth_method->name); } if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { *pauthoritative = 0; nt_status = NT_STATUS_NO_SUCH_USER; } if (!NT_STATUS_IS_OK(nt_status)) { DBG_INFO("%s authentication for user [%s] FAILED with " "error %s, authoritative=%u\n", auth_method_name, user_info->client.account_name, nt_errstr(nt_status), *pauthoritative); goto fail; } DBG_NOTICE("%s authentication for user [%s] succeeded\n", auth_method_name, user_info->client.account_name); unix_username = server_info->unix_name; /* We skip doing this step if the caller asked us not to */ if (!(user_info->flags & USER_INFO_INFO3_AND_NO_AUTHZ) && !(server_info->guest)) { const char *rhost; if (tsocket_address_is_inet(user_info->remote_host, "ip")) { rhost = tsocket_address_inet_addr_string( user_info->remote_host, talloc_tos()); if (rhost == NULL) { nt_status = NT_STATUS_NO_MEMORY; goto fail; } } else { rhost = "127.0.0.1"; } /* We might not be root if we are an RPC call */ become_root(); nt_status = smb_pam_accountcheck(unix_username, rhost); unbecome_root(); if (NT_STATUS_IS_OK(nt_status)) { DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] " "succeeded\n", unix_username)); } else { DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] " "FAILED with error %s\n", unix_username, nt_errstr(nt_status))); } } if (!NT_STATUS_IS_OK(nt_status)) { goto fail; } nt_status = get_user_sid_info3_and_extra(server_info->info3, &server_info->extra, &sid); if (!NT_STATUS_IS_OK(nt_status)) { sid = (struct dom_sid) {0}; } log_authentication_event(NULL, NULL, user_info, nt_status, server_info->info3->base.logon_domain.string, server_info->info3->base.account_name.string, unix_username, &sid); DEBUG(server_info->guest ? 5 : 2, ("check_ntlm_password: %sauthentication for user " "[%s] -> [%s] -> [%s] succeeded\n", server_info->guest ? "guest " : "", user_info->client.account_name, user_info->mapped.account_name, unix_username)); *pserver_info = talloc_move(mem_ctx, &server_info); TALLOC_FREE(frame); return NT_STATUS_OK; fail: /* failed authentication; check for guest lapping */ /* * Please try not to change this string, it is probably in use * in audit logging tools */ DEBUG(2, ("check_ntlm_password: Authentication for user " "[%s] -> [%s] FAILED with error %s, authoritative=%u\n", user_info->client.account_name, user_info->mapped.account_name, nt_errstr(nt_status), *pauthoritative)); log_authentication_event(NULL, NULL, user_info, nt_status, NULL, NULL, NULL, NULL); ZERO_STRUCTP(pserver_info); TALLOC_FREE(frame); return nt_status; }