⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 credentials_krb5.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   Handle user credentials (as regards krb5)   Copyright (C) Jelmer Vernooij 2005   Copyright (C) Tim Potter 2001   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 3 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program.  If not, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "system/kerberos.h"#include "auth/kerberos/kerberos.h"#include "auth/credentials/credentials.h"#include "auth/credentials/credentials_proto.h"#include "auth/credentials/credentials_krb5.h"#include "param/param.h"_PUBLIC_ int cli_credentials_get_krb5_context(struct cli_credentials *cred, 					      struct event_context *event_ctx,				     struct loadparm_context *lp_ctx,				     struct smb_krb5_context **smb_krb5_context) {	int ret;	if (cred->smb_krb5_context) {		*smb_krb5_context = cred->smb_krb5_context;		return 0;	}	ret = smb_krb5_init_context(cred, event_ctx, lp_ctx, &cred->smb_krb5_context);	if (ret) {		cred->smb_krb5_context = NULL;		return ret;	}	*smb_krb5_context = cred->smb_krb5_context;	return 0;}/* This needs to be called directly after the cli_credentials_init(), * otherwise we might have problems with the krb5 context already * being here. */_PUBLIC_ NTSTATUS cli_credentials_set_krb5_context(struct cli_credentials *cred, 					  struct smb_krb5_context *smb_krb5_context){	if (!talloc_reference(cred, smb_krb5_context)) {		return NT_STATUS_NO_MEMORY;	}	cred->smb_krb5_context = smb_krb5_context;	return NT_STATUS_OK;}static int cli_credentials_set_from_ccache(struct cli_credentials *cred, 				    struct ccache_container *ccache,				    enum credentials_obtained obtained){		krb5_principal princ;	krb5_error_code ret;	char *name;	char **realm;	if (cred->ccache_obtained > obtained) {		return 0;	}	ret = krb5_cc_get_principal(ccache->smb_krb5_context->krb5_context, 				    ccache->ccache, &princ);	if (ret) {		char *err_mess = smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, 							    ret, cred);		DEBUG(1,("failed to get principal from ccache: %s\n", 			 err_mess));		talloc_free(err_mess);		return ret;	}		ret = krb5_unparse_name(ccache->smb_krb5_context->krb5_context, princ, &name);	if (ret) {		char *err_mess = smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, ret, cred);		DEBUG(1,("failed to unparse principal from ccache: %s\n", 			 err_mess));		talloc_free(err_mess);		return ret;	}	realm = krb5_princ_realm(ccache->smb_krb5_context->krb5_context, princ);	cli_credentials_set_principal(cred, name, obtained);	free(name);	krb5_free_principal(ccache->smb_krb5_context->krb5_context, princ);	/* set the ccache_obtained here, as it just got set to UNINITIALISED by the calls above */	cred->ccache_obtained = obtained;	return 0;}/* Free a memory ccache */static int free_mccache(struct ccache_container *ccc){	krb5_cc_destroy(ccc->smb_krb5_context->krb5_context, ccc->ccache);	return 0;}/* Free a disk-based ccache */static int free_dccache(struct ccache_container *ccc) {	krb5_cc_close(ccc->smb_krb5_context->krb5_context, ccc->ccache);	return 0;}_PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred, 					struct event_context *event_ctx,			       struct loadparm_context *lp_ctx,			       const char *name, 			       enum credentials_obtained obtained){	krb5_error_code ret;	krb5_principal princ;	struct ccache_container *ccc;	if (cred->ccache_obtained > obtained) {		return 0;	}	ccc = talloc(cred, struct ccache_container);	if (!ccc) {		return ENOMEM;	}	ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, 					       &ccc->smb_krb5_context);	if (ret) {		talloc_free(ccc);		return ret;	}	if (!talloc_reference(ccc, ccc->smb_krb5_context)) {		talloc_free(ccc);		return ENOMEM;	}	if (name) {		ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache);		if (ret) {			DEBUG(1,("failed to read krb5 ccache: %s: %s\n", 				 name, 				 smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));			talloc_free(ccc);			return ret;		}	} else {		ret = krb5_cc_default(ccc->smb_krb5_context->krb5_context, &ccc->ccache);		if (ret) {			DEBUG(3,("failed to read default krb5 ccache: %s\n", 				 smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));			talloc_free(ccc);			return ret;		}	}	talloc_set_destructor(ccc, free_dccache);	ret = krb5_cc_get_principal(ccc->smb_krb5_context->krb5_context, ccc->ccache, &princ);	if (ret) {		DEBUG(3,("failed to get principal from default ccache: %s\n", 			 smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));		talloc_free(ccc);				return ret;	}	krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ);	ret = cli_credentials_set_from_ccache(cred, ccc, obtained);	if (ret) {		return ret;	}	cred->ccache = ccc;	cred->ccache_obtained = obtained;	talloc_steal(cred, ccc);	cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained);	return 0;}static int cli_credentials_new_ccache(struct cli_credentials *cred, 				      struct event_context *event_ctx,				      struct loadparm_context *lp_ctx,				      struct ccache_container **_ccc){	krb5_error_code ret;	struct ccache_container *ccc = talloc(cred, struct ccache_container);	char *ccache_name;	if (!ccc) {		return ENOMEM;	}	ccache_name = talloc_asprintf(ccc, "MEMORY:%p", 				      ccc);	if (!ccache_name) {		talloc_free(ccc);		return ENOMEM;	}	ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, 					       &ccc->smb_krb5_context);	if (ret) {		talloc_free(ccc);		return ret;	}	if (!talloc_reference(ccc, ccc->smb_krb5_context)) {		talloc_free(ccc);		return ENOMEM;	}	ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, ccache_name, 			      &ccc->ccache);	if (ret) {		DEBUG(1,("failed to generate a new krb5 ccache (%s): %s\n", 			 ccache_name,			 smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));		talloc_free(ccache_name);		talloc_free(ccc);		return ret;	}	talloc_set_destructor(ccc, free_mccache);	talloc_free(ccache_name);	*_ccc = ccc;	return ret;}_PUBLIC_ int cli_credentials_get_ccache(struct cli_credentials *cred, 					struct event_context *event_ctx,			       struct loadparm_context *lp_ctx,			       struct ccache_container **ccc){	krb5_error_code ret;		if (cred->machine_account_pending) {		cli_credentials_set_machine_account(cred, lp_ctx);	}	if (cred->ccache_obtained >= cred->ccache_threshold && 	    cred->ccache_obtained > CRED_UNINITIALISED) {		*ccc = cred->ccache;		return 0;	}	if (cli_credentials_is_anonymous(cred)) {		return EINVAL;	}	ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, ccc);	if (ret) {		return ret;	}	ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, (*ccc)->ccache);	if (ret) {		return ret;	}	ret = cli_credentials_set_from_ccache(cred, *ccc, 					      (MAX(MAX(cred->principal_obtained, 						       cred->username_obtained), 						   cred->password_obtained)));		cred->ccache = *ccc;	cred->ccache_obtained = cred->principal_obtained;	if (ret) {		return ret;	}	cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained);	return ret;}void cli_credentials_invalidate_client_gss_creds(struct cli_credentials *cred, 						 enum credentials_obtained obtained){	/* If the caller just changed the username/password etc, then	 * any cached credentials are now invalid */	if (obtained >= cred->client_gss_creds_obtained) {		if (cred->client_gss_creds_obtained > CRED_UNINITIALISED) {			talloc_unlink(cred, cred->client_gss_creds);			cred->client_gss_creds = NULL;		}		cred->client_gss_creds_obtained = CRED_UNINITIALISED;	}	/* Now that we know that the data is 'this specified', then	 * don't allow something less 'known' to be returned as a	 * ccache.  Ie, if the username is on the commmand line, we	 * don't want to later guess to use a file-based ccache */	if (obtained > cred->client_gss_creds_threshold) {		cred->client_gss_creds_threshold = obtained;	}}_PUBLIC_ void cli_credentials_invalidate_ccache(struct cli_credentials *cred, 				       enum credentials_obtained obtained){	/* If the caller just changed the username/password etc, then	 * any cached credentials are now invalid */	if (obtained >= cred->ccache_obtained) {		if (cred->ccache_obtained > CRED_UNINITIALISED) {			talloc_unlink(cred, cred->ccache);			cred->ccache = NULL;		}		cred->ccache_obtained = CRED_UNINITIALISED;	}	/* Now that we know that the data is 'this specified', then	 * don't allow something less 'known' to be returned as a	 * ccache.  Ie, if the username is on the commmand line, we	 * don't want to later guess to use a file-based ccache */	if (obtained > cred->ccache_threshold) {		cred->ccache_threshold  = obtained;	}	cli_credentials_invalidate_client_gss_creds(cred, 						    obtained);}static int free_gssapi_creds(struct gssapi_creds_container *gcc){	OM_uint32 min_stat, maj_stat;	maj_stat = gss_release_cred(&min_stat, &gcc->creds);	return 0;}_PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, 					 struct event_context *event_ctx,					 struct loadparm_context *lp_ctx,					 struct gssapi_creds_container **_gcc) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -