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

📄 kerberos_pac.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
		file_save("tmp_pac_data-admin.dat",blob.data,blob.length);	}#endif	DEBUG(3,("Found account name from PAC: %s [%s]\n",		 logon_info->info3.base.account_name.string, 		 logon_info->info3.base.full_name.string));	*pac_data_out = pac_data;	return NT_STATUS_OK;}_PUBLIC_  NTSTATUS kerberos_pac_logon_info(TALLOC_CTX *mem_ctx,				  struct smb_iconv_convenience *iconv_convenience,				  struct PAC_LOGON_INFO **logon_info,				  DATA_BLOB blob,				  krb5_context context,				  const krb5_keyblock *krbtgt_keyblock,				  const krb5_keyblock *service_keyblock,				  krb5_const_principal client_principal,				  time_t tgs_authtime, 				  krb5_error_code *k5ret){	NTSTATUS nt_status;	struct PAC_DATA *pac_data;	int i;	nt_status = kerberos_decode_pac(mem_ctx, 					iconv_convenience,					&pac_data,					blob,					context,					krbtgt_keyblock,					service_keyblock,					client_principal, 					tgs_authtime,					k5ret);	if (!NT_STATUS_IS_OK(nt_status)) {		return nt_status;	}	*logon_info = NULL;	for (i=0; i < pac_data->num_buffers; i++) {		if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) {			continue;		}		*logon_info = pac_data->buffers[i].info->logon_info.info; 	}	if (!*logon_info) {		return NT_STATUS_INVALID_PARAMETER;	}	return NT_STATUS_OK;}static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx, 					 DATA_BLOB *pac_data,					 struct PAC_SIGNATURE_DATA *sig,					 krb5_context context,					 const krb5_keyblock *keyblock){	krb5_error_code ret;	krb5_crypto crypto;	Checksum cksum;	ret = krb5_crypto_init(context,			       keyblock,			       0,			       &crypto);	if (ret) {		DEBUG(0,("krb5_crypto_init() failed: %s\n",			  smb_get_krb5_error_message(context, ret, mem_ctx)));		return ret;	}	ret = krb5_create_checksum(context,				   crypto,				   KRB5_KU_OTHER_CKSUM,				   0,				   pac_data->data,				   pac_data->length,				   &cksum);	if (ret) {		DEBUG(2, ("PAC Verification failed: %s\n", 			  smb_get_krb5_error_message(context, ret, mem_ctx)));	}	krb5_crypto_destroy(context, crypto);	if (ret) {		return ret;	}	sig->type = cksum.cksumtype;	sig->signature = data_blob_talloc(mem_ctx, cksum.checksum.data, cksum.checksum.length);	free_Checksum(&cksum);	return 0;} krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx,				     struct smb_iconv_convenience *iconv_convenience,				    struct PAC_DATA *pac_data,				    krb5_context context,				    const krb5_keyblock *krbtgt_keyblock,				    const krb5_keyblock *service_keyblock,				    DATA_BLOB *pac) {	NTSTATUS nt_status;	krb5_error_code ret;	enum ndr_err_code ndr_err;	DATA_BLOB zero_blob = data_blob(NULL, 0);	DATA_BLOB tmp_blob = data_blob(NULL, 0);	struct PAC_SIGNATURE_DATA *kdc_checksum = NULL;	struct PAC_SIGNATURE_DATA *srv_checksum = NULL;	int i;	/* First, just get the keytypes filled in (and lengths right, eventually) */	for (i=0; i < pac_data->num_buffers; i++) {		if (pac_data->buffers[i].type != PAC_TYPE_KDC_CHECKSUM) {			continue;		}		kdc_checksum = &pac_data->buffers[i].info->kdc_cksum, 		ret = make_pac_checksum(mem_ctx, &zero_blob,					kdc_checksum, 					context, krbtgt_keyblock);		if (ret) {			DEBUG(2, ("making krbtgt PAC checksum failed: %s\n", 				  smb_get_krb5_error_message(context, ret, mem_ctx)));			talloc_free(pac_data);			return ret;		}	}		for (i=0; i < pac_data->num_buffers; i++) {		if (pac_data->buffers[i].type != PAC_TYPE_SRV_CHECKSUM) {			continue;		}		srv_checksum = &pac_data->buffers[i].info->srv_cksum; 		ret = make_pac_checksum(mem_ctx, &zero_blob, 					srv_checksum, 					context, service_keyblock);		if (ret) {			DEBUG(2, ("making service PAC checksum failed: %s\n", 				  smb_get_krb5_error_message(context, ret, mem_ctx)));			talloc_free(pac_data);			return ret;		}	}	if (!kdc_checksum) {		DEBUG(2, ("Invalid PAC constructed for signing, no KDC checksum present!"));		return EINVAL;	}	if (!srv_checksum) {		DEBUG(2, ("Invalid PAC constructed for signing, no SRV checksum present!"));		return EINVAL;	}	/* But wipe out the actual signatures */	memset(kdc_checksum->signature.data, '\0', kdc_checksum->signature.length);	memset(srv_checksum->signature.data, '\0', srv_checksum->signature.length);	ndr_err = ndr_push_struct_blob(&tmp_blob, mem_ctx, 				       iconv_convenience,				       pac_data,				       (ndr_push_flags_fn_t)ndr_push_PAC_DATA);	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {		nt_status = ndr_map_error2ntstatus(ndr_err);		DEBUG(1, ("PAC (presig) push failed: %s\n", nt_errstr(nt_status)));		talloc_free(pac_data);		return EINVAL;	}	/* Then sign the result of the previous push, where the sig was zero'ed out */	ret = make_pac_checksum(mem_ctx, &tmp_blob, srv_checksum,				context, service_keyblock);	/* Then sign Server checksum */	ret = make_pac_checksum(mem_ctx, &srv_checksum->signature, kdc_checksum, context, krbtgt_keyblock);	if (ret) {		DEBUG(2, ("making krbtgt PAC checksum failed: %s\n", 			  smb_get_krb5_error_message(context, ret, mem_ctx)));		talloc_free(pac_data);		return ret;	}	/* And push it out again, this time to the world.  This relies on determanistic pointer values */	ndr_err = ndr_push_struct_blob(&tmp_blob, mem_ctx, 				       iconv_convenience,				       pac_data,				       (ndr_push_flags_fn_t)ndr_push_PAC_DATA);	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {		nt_status = ndr_map_error2ntstatus(ndr_err);		DEBUG(1, ("PAC (final) push failed: %s\n", nt_errstr(nt_status)));		talloc_free(pac_data);		return EINVAL;	}	*pac = tmp_blob;	return ret;} krb5_error_code kerberos_create_pac(TALLOC_CTX *mem_ctx,				     struct smb_iconv_convenience *iconv_convenience,				     struct auth_serversupplied_info *server_info,				     krb5_context context,				     const krb5_keyblock *krbtgt_keyblock,				     const krb5_keyblock *service_keyblock,				     krb5_principal client_principal,				     time_t tgs_authtime,				     DATA_BLOB *pac){	NTSTATUS nt_status;	krb5_error_code ret;	struct PAC_DATA *pac_data = talloc(mem_ctx, struct PAC_DATA);	struct netr_SamInfo3 *sam3;	union PAC_INFO *u_LOGON_INFO;	struct PAC_LOGON_INFO *LOGON_INFO;	union PAC_INFO *u_LOGON_NAME;	struct PAC_LOGON_NAME *LOGON_NAME;	union PAC_INFO *u_KDC_CHECKSUM;	union PAC_INFO *u_SRV_CHECKSUM;	char *name;			enum {		PAC_BUF_LOGON_INFO = 0,		PAC_BUF_LOGON_NAME = 1,		PAC_BUF_SRV_CHECKSUM = 2,		PAC_BUF_KDC_CHECKSUM = 3,		PAC_BUF_NUM_BUFFERS = 4	};	if (!pac_data) {		return ENOMEM;	}	pac_data->num_buffers = PAC_BUF_NUM_BUFFERS;	pac_data->version = 0;	pac_data->buffers = talloc_array(pac_data, 					 struct PAC_BUFFER,					 pac_data->num_buffers);	if (!pac_data->buffers) {		talloc_free(pac_data);		return ENOMEM;	}	/* LOGON_INFO */	u_LOGON_INFO = talloc_zero(pac_data->buffers, union PAC_INFO);	if (!u_LOGON_INFO) {		talloc_free(pac_data);		return ENOMEM;	}	pac_data->buffers[PAC_BUF_LOGON_INFO].type = PAC_TYPE_LOGON_INFO;	pac_data->buffers[PAC_BUF_LOGON_INFO].info = u_LOGON_INFO;	/* LOGON_NAME */	u_LOGON_NAME = talloc_zero(pac_data->buffers, union PAC_INFO);	if (!u_LOGON_NAME) {		talloc_free(pac_data);		return ENOMEM;	}	pac_data->buffers[PAC_BUF_LOGON_NAME].type = PAC_TYPE_LOGON_NAME;	pac_data->buffers[PAC_BUF_LOGON_NAME].info = u_LOGON_NAME;	LOGON_NAME = &u_LOGON_NAME->logon_name;	/* SRV_CHECKSUM */	u_SRV_CHECKSUM = talloc_zero(pac_data->buffers, union PAC_INFO);	if (!u_SRV_CHECKSUM) {		talloc_free(pac_data);		return ENOMEM;	}	pac_data->buffers[PAC_BUF_SRV_CHECKSUM].type = PAC_TYPE_SRV_CHECKSUM;	pac_data->buffers[PAC_BUF_SRV_CHECKSUM].info = u_SRV_CHECKSUM;	/* KDC_CHECKSUM */	u_KDC_CHECKSUM = talloc_zero(pac_data->buffers, union PAC_INFO);	if (!u_KDC_CHECKSUM) {		talloc_free(pac_data);		return ENOMEM;	}	pac_data->buffers[PAC_BUF_KDC_CHECKSUM].type = PAC_TYPE_KDC_CHECKSUM;	pac_data->buffers[PAC_BUF_KDC_CHECKSUM].info = u_KDC_CHECKSUM;	/* now the real work begins... */	LOGON_INFO = talloc_zero(u_LOGON_INFO, struct PAC_LOGON_INFO);	if (!LOGON_INFO) {		talloc_free(pac_data);		return ENOMEM;	}	nt_status = auth_convert_server_info_saminfo3(LOGON_INFO, server_info, &sam3);	if (!NT_STATUS_IS_OK(nt_status)) {		DEBUG(1, ("Getting Samba info failed: %s\n", nt_errstr(nt_status)));		talloc_free(pac_data);		return EINVAL;	}	u_LOGON_INFO->logon_info.info		= LOGON_INFO;	LOGON_INFO->info3 = *sam3;	ret = krb5_unparse_name_flags(context, client_principal, 				      KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);	if (ret) {		return ret;	}	LOGON_NAME->account_name	= talloc_strdup(LOGON_NAME, name);	free(name);	/*	  this logon_time field is absolutely critical. This is what	  caused all our PAC troubles :-)	*/	unix_to_nt_time(&LOGON_NAME->logon_time, tgs_authtime);	ret = kerberos_encode_pac(mem_ctx, 				  iconv_convenience,				  pac_data, 				  context,				  krbtgt_keyblock,				  service_keyblock,				  pac);	talloc_free(pac_data);	return ret;}

⌨️ 快捷键说明

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