/* Produce a session_info for an arbitary DN or principal in the local * DB, assuming the local DB holds all the groups * * Supply either a principal or a DN */ NTSTATUS authsam_get_session_info_principal(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct ldb_context *sam_ctx, const char *principal, struct ldb_dn *user_dn, uint32_t session_info_flags, struct auth_session_info **session_info) { NTSTATUS nt_status; struct auth_user_info_dc *user_info_dc; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { return NT_STATUS_NO_MEMORY; } nt_status = authsam_get_user_info_dc_principal(tmp_ctx, lp_ctx, sam_ctx, principal, user_dn, &user_info_dc); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return nt_status; } nt_status = auth_generate_session_info(tmp_ctx, lp_ctx, sam_ctx, user_info_dc, session_info_flags, session_info); if (NT_STATUS_IS_OK(nt_status)) { talloc_steal(mem_ctx, *session_info); } talloc_free(tmp_ctx); return nt_status; }
NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, struct loadparm_context *lp_ctx, struct auth_session_info **_session_info) { NTSTATUS nt_status; struct auth_user_info_dc *user_info_dc = NULL; struct auth_session_info *session_info = NULL; TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); nt_status = auth_system_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx), &user_info_dc); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } /* references the user_info_dc into the session_info */ nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info); talloc_free(mem_ctx); NT_STATUS_NOT_OK_RETURN(nt_status); session_info->credentials = cli_credentials_init(session_info); if (!session_info->credentials) { return NT_STATUS_NO_MEMORY; } cli_credentials_set_conf(session_info->credentials, lp_ctx); cli_credentials_set_machine_account_pending(session_info->credentials, lp_ctx); *_session_info = session_info; return NT_STATUS_OK; }
/* * Create session info from PAC * This is called as auth_context->generate_session_info_pac() */ static NTSTATUS b9_generate_session_info_pac(struct auth4_context *auth_context, TALLOC_CTX *mem_ctx, struct smb_krb5_context *smb_krb5_context, DATA_BLOB *pac_blob, const char *principal_name, const struct tsocket_address *remote_addr, uint32_t session_info_flags, struct auth_session_info **session_info) { NTSTATUS status; struct auth_user_info_dc *user_info_dc; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(mem_ctx); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); status = kerberos_pac_blob_to_user_info_dc(tmp_ctx, *pac_blob, smb_krb5_context->krb5_context, &user_info_dc, NULL, NULL); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return status; } if (user_info_dc->info->authenticated) { session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED; } session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES; status = auth_generate_session_info(mem_ctx, NULL, NULL, user_info_dc, session_info_flags, session_info); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return status; } talloc_free(tmp_ctx); return status; }
_PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, struct auth_session_info **_session_info) { NTSTATUS nt_status; struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); nt_status = auth_anonymous_server_info(mem_ctx, lp_netbios_name(lp_ctx), &server_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } /* references the server_info into the session_info */ nt_status = auth_generate_session_info(parent_ctx, event_ctx, lp_ctx, server_info, &session_info); talloc_free(mem_ctx); NT_STATUS_NOT_OK_RETURN(nt_status); session_info->credentials = cli_credentials_init(session_info); if (!session_info->credentials) { return NT_STATUS_NO_MEMORY; } cli_credentials_set_conf(session_info->credentials, lp_ctx); cli_credentials_set_anonymous(session_info->credentials); *_session_info = session_info; return NT_STATUS_OK; }
static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security, struct auth_session_info **_session_info) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; struct gensec_krb5_state *gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data; krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context; struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info = NULL; struct PAC_LOGON_INFO *logon_info; krb5_principal client_principal; char *principal_string; DATA_BLOB pac; krb5_data pac_data; krb5_error_code ret; TALLOC_CTX *mem_ctx = talloc_new(gensec_security); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } ret = krb5_ticket_get_client(context, gensec_krb5_state->ticket, &client_principal); if (ret) { DEBUG(5, ("krb5_ticket_get_client failed to get cleint principal: %s\n", smb_get_krb5_error_message(context, ret, mem_ctx))); talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } ret = krb5_unparse_name(gensec_krb5_state->smb_krb5_context->krb5_context, client_principal, &principal_string); if (ret) { DEBUG(1, ("Unable to parse client principal: %s\n", smb_get_krb5_error_message(context, ret, mem_ctx))); talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } ret = krb5_ticket_get_authorization_data_type(context, gensec_krb5_state->ticket, KRB5_AUTHDATA_WIN2K_PAC, &pac_data); if (ret && gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access: %s \n", principal_string, smb_get_krb5_error_message(context, ret, mem_ctx))); krb5_free_principal(context, client_principal); free(principal_string); return NT_STATUS_ACCESS_DENIED; } else if (ret) { /* NO pac */ DEBUG(5, ("krb5_ticket_get_authorization_data_type failed to find PAC: %s\n", smb_get_krb5_error_message(context, ret, mem_ctx))); if (gensec_security->auth_context && !gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { DEBUG(1, ("Unable to find PAC for %s, resorting to local user lookup: %s", principal_string, smb_get_krb5_error_message(context, ret, mem_ctx))); nt_status = gensec_security->auth_context->get_server_info_principal(mem_ctx, gensec_security->auth_context, principal_string, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } } else { DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n", principal_string)); return NT_STATUS_ACCESS_DENIED; } krb5_free_principal(context, client_principal); free(principal_string); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } } else { /* Found pac */ union netr_Validation validation; free(principal_string); pac = data_blob_talloc(mem_ctx, pac_data.data, pac_data.length); if (!pac.data) { krb5_free_principal(context, client_principal); talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } /* decode and verify the pac */ nt_status = kerberos_pac_logon_info(gensec_krb5_state, gensec_security->settings->iconv_convenience, &logon_info, pac, gensec_krb5_state->smb_krb5_context->krb5_context, NULL, gensec_krb5_state->keyblock, client_principal, gensec_krb5_state->ticket->ticket.authtime, NULL); krb5_free_principal(context, client_principal); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } validation.sam3 = &logon_info->info3; nt_status = make_server_info_netlogon_validation(mem_ctx, NULL, 3, &validation, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } } /* references the server_info into the session_info */ nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, gensec_security->settings->lp_ctx, server_info, &session_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } nt_status = gensec_krb5_session_key(gensec_security, &session_info->session_key); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } *_session_info = session_info; talloc_steal(gensec_krb5_state, session_info); talloc_free(mem_ctx); return NT_STATUS_OK; }
int mit_samba_kpasswd_change_password(struct mit_samba_context *ctx, char *pwd, krb5_db_entry *db_entry) { NTSTATUS status; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; TALLOC_CTX *tmp_ctx; DATA_BLOB password; enum samPwdChangeReason reject_reason; struct samr_DomInfo1 *dominfo; const char *error_string = NULL; struct auth_user_info_dc *user_info_dc; struct samba_kdc_entry *p; krb5_error_code code = 0; #ifdef DEBUG_PASSWORD DEBUG(1,("mit_samba_kpasswd_change_password called with: %s\n", pwd)); #endif tmp_ctx = talloc_named(ctx, 0, "mit_samba_kpasswd_change_password"); if (tmp_ctx == NULL) { return ENOMEM; } p = (struct samba_kdc_entry *)db_entry->e_data; status = authsam_make_user_info_dc(tmp_ctx, ctx->db_ctx->samdb, lpcfg_netbios_name(ctx->db_ctx->lp_ctx), lpcfg_sam_name(ctx->db_ctx->lp_ctx), p->realm_dn, p->msg, data_blob(NULL, 0), data_blob(NULL, 0), &user_info_dc); if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("authsam_make_user_info_dc failed: %s\n", nt_errstr(status))); talloc_free(tmp_ctx); return EINVAL; } status = auth_generate_session_info(tmp_ctx, ctx->db_ctx->lp_ctx, ctx->db_ctx->samdb, user_info_dc, 0, /* session_info_flags */ &ctx->session_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("auth_generate_session_info failed: %s\n", nt_errstr(status))); talloc_free(tmp_ctx); return EINVAL; } /* password is expected as UTF16 */ if (!convert_string_talloc(tmp_ctx, CH_UTF8, CH_UTF16, pwd, strlen(pwd), &password.data, &password.length)) { DEBUG(1,("convert_string_talloc failed\n")); talloc_free(tmp_ctx); return EINVAL; } status = samdb_kpasswd_change_password(tmp_ctx, ctx->db_ctx->lp_ctx, ctx->db_ctx->ev_ctx, ctx->db_ctx->samdb, ctx->session_info, &password, &reject_reason, &dominfo, &error_string, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("samdb_kpasswd_change_password failed: %s\n", nt_errstr(status))); code = KADM5_PASS_Q_GENERIC; krb5_set_error_message(ctx->context, code, "%s", error_string); goto out; } if (!NT_STATUS_IS_OK(result)) { code = mit_samba_change_pwd_error(ctx->context, result, reject_reason, dominfo); } out: talloc_free(tmp_ctx); return code; }
_PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, struct event_context *ev, struct messaging_context *msg, const char *nt4_domain, const char *nt4_username, const char *password, struct auth_session_info **session_info) { struct auth_context *auth_context; struct auth_usersupplied_info *user_info; struct auth_serversupplied_info *server_info; NTSTATUS nt_status; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { return NT_STATUS_NO_MEMORY; } nt_status = auth_context_create(tmp_ctx, lp_auth_methods(), ev, msg, &auth_context); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return nt_status; } user_info = talloc(tmp_ctx, struct auth_usersupplied_info); if (!user_info) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } user_info->mapped_state = True; user_info->client.account_name = nt4_username; user_info->mapped.account_name = nt4_username; user_info->client.domain_name = nt4_domain; user_info->mapped.domain_name = nt4_domain; user_info->workstation_name = NULL; user_info->remote_host = NULL; user_info->password_state = AUTH_PASSWORD_PLAIN; user_info->password.plaintext = talloc_strdup(user_info, password); user_info->flags = USER_INFO_CASE_INSENSITIVE_USERNAME | USER_INFO_DONT_CHECK_UNIX_ACCOUNT; user_info->logon_parameters = 0; nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return nt_status; } nt_status = auth_generate_session_info(tmp_ctx, server_info, session_info); if (NT_STATUS_IS_OK(nt_status)) { talloc_steal(mem_ctx, *session_info); } return nt_status; }