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

📄 krb5tgs.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
	cross_realm = 1;    }        /*     * Check that service is in the same realm as the krbtgt. If it's     * not the same, it's someone that is using a uni-directional trust     * backward.     */        if (strcmp(krb5_principal_get_realm(context, sp),	       krb5_principal_get_comp_string(context, 					      krbtgt->entry.principal, 					      1)) != 0) {	char *tpn;	ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn);	kdc_log(context, config, 0,		"Request with wrong krbtgt: %s",		(ret == 0) ? tpn : "<unknown>");	if(ret == 0)	    free(tpn);	ret = KRB5KRB_AP_ERR_NOT_US;	goto out;    }    /*     *     */    client_principal = cp;    if (client) {	const PA_DATA *sdata;	int i = 0;	sdata = _kdc_find_padata(req, &i, KRB5_PADATA_S4U2SELF);	if (sdata) {	    krb5_crypto crypto;	    krb5_data datack;	    PA_S4U2Self self;	    char *selfcpn = NULL;	    const char *str;	    ret = decode_PA_S4U2Self(sdata->padata_value.data, 				     sdata->padata_value.length,				     &self, NULL);	    if (ret) {		kdc_log(context, config, 0, "Failed to decode PA-S4U2Self");		goto out;	    }	    ret = _krb5_s4u2self_to_checksumdata(context, &self, &datack);	    if (ret)		goto out;	    ret = krb5_crypto_init(context, &tgt->key, 0, &crypto);	    if (ret) {		free_PA_S4U2Self(&self);		krb5_data_free(&datack);		kdc_log(context, config, 0, "krb5_crypto_init failed: %s",			krb5_get_err_text(context, ret));		goto out;	    }	    ret = krb5_verify_checksum(context,				       crypto,				       KRB5_KU_OTHER_CKSUM,				       datack.data, 				       datack.length, 				       &self.cksum);	    krb5_data_free(&datack);	    krb5_crypto_destroy(context, crypto);	    if (ret) {		free_PA_S4U2Self(&self);		kdc_log(context, config, 0, 			"krb5_verify_checksum failed for S4U2Self: %s",			krb5_get_err_text(context, ret));		goto out;	    }	    ret = _krb5_principalname2krb5_principal(context,						     &client_principal,						     self.name,						     self.realm);	    free_PA_S4U2Self(&self);	    if (ret)		goto out;	    ret = krb5_unparse_name(context, client_principal, &selfcpn);		    if (ret)		goto out;	    /*	     * Check that service doing the impersonating is	     * requesting a ticket to it-self.	     */	    if (krb5_principal_compare(context, cp, sp) != TRUE) {		kdc_log(context, config, 0, "S4U2Self: %s is not allowed "			"to impersonate some other user "			"(tried for user %s to service %s)",			cpn, selfcpn, spn);		free(selfcpn);		ret = KRB5KDC_ERR_BADOPTION; /* ? */		goto out;	    }	    /*	     * If the service isn't trusted for authentication to	     * delegation, remove the forward flag.	     */	    if (client->entry.flags.trusted_for_delegation) {		str = "[forwardable]";	    } else {		b->kdc_options.forwardable = 0;		str = "";	    }	    kdc_log(context, config, 0, "s4u2self %s impersonating %s to "		    "service %s %s", cpn, selfcpn, spn, str);	    free(selfcpn);	}    }    /*     * Constrained delegation     */    if (client != NULL	&& b->additional_tickets != NULL	&& b->additional_tickets->len != 0	&& b->kdc_options.enc_tkt_in_skey == 0)    {	Key *clientkey;	Ticket *t;	char *str;	t = &b->additional_tickets->val[0];	ret = hdb_enctype2key(context, &client->entry, 			      t->enc_part.etype, &clientkey);	if(ret){	    ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */	    goto out;	}	ret = krb5_decrypt_ticket(context, t, &clientkey->key, &adtkt, 0);	if (ret) {	    kdc_log(context, config, 0,		    "failed to decrypt ticket for "		    "constrained delegation from %s to %s ", spn, cpn);	    goto out;	}	/* check that ticket is valid */	if (adtkt.flags.forwardable == 0) {	    kdc_log(context, config, 0,		    "Missing forwardable flag on ticket for "		    "constrained delegation from %s to %s ", spn, cpn);	    ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */	    goto out;	}	ret = check_constrained_delegation(context, config, client, sp);	if (ret) {	    kdc_log(context, config, 0,		    "constrained delegation from %s to %s not allowed", 		    spn, cpn);	    goto out;	}	ret = _krb5_principalname2krb5_principal(context,						 &client_principal,						 adtkt.cname,						 adtkt.crealm);	if (ret)	    goto out;	ret = krb5_unparse_name(context, client_principal, &str);	if (ret)	    goto out;	ret = verify_flags(context, config, &adtkt, str);	if (ret) {	    free(str);	    goto out;	}	/*	 * Check KRB5SignedPath in authorization data and add new entry to	 * make sure servers can't fake a ticket to us.	 */	ret = check_KRB5SignedPath(context,				   config,				   krbtgt,				   &adtkt,				   &spp,				   1);	if (ret) {	    kdc_log(context, config, 0,		    "KRB5SignedPath check from service %s failed "		    "for delegation to %s for client %s "		    "from %s failed with %s",		    spn, str, cpn, from, krb5_get_err_text(context, ret));	    free(str);	    goto out;	}	kdc_log(context, config, 0, "constrained delegation for %s "		"from %s to %s", str, cpn, spn);	free(str);	/* 	 * Also require that the KDC have issue the service's krbtgt	 * used to do the request. 	 */	require_signedpath = 1;    }    /*     * Check flags     */    ret = _kdc_check_flags(context, config, 			   client, cpn,			   server, spn,			   FALSE);    if(ret)	goto out;    if((b->kdc_options.validate || b->kdc_options.renew) &&        !krb5_principal_compare(context, 			       krbtgt->entry.principal,			       server->entry.principal)){	kdc_log(context, config, 0, "Inconsistent request.");	ret = KRB5KDC_ERR_SERVER_NOMATCH;	goto out;    }    /* check for valid set of addresses */    if(!_kdc_check_addresses(context, config, tgt->caddr, from_addr)) {	ret = KRB5KRB_AP_ERR_BADADDR;	kdc_log(context, config, 0, "Request from wrong address");	goto out;    }	    /*     * Select enctype, return key and kvno.     */    {	krb5_enctype etype;	if(b->kdc_options.enc_tkt_in_skey) {	    int i;	    ekey = &adtkt.key;	    for(i = 0; i < b->etype.len; i++)		if (b->etype.val[i] == adtkt.key.keytype)		    break;	    if(i == b->etype.len) {		krb5_clear_error_string(context);		return KRB5KDC_ERR_ETYPE_NOSUPP;	    }	    etype = b->etype.val[i];	    kvno = 0;	} else {	    Key *skey;	    	    ret = _kdc_find_etype(context, server, b->etype.val, b->etype.len,				  &skey, &etype);	    if(ret) {		kdc_log(context, config, 0, 			"Server (%s) has no support for etypes", spp);		return ret;	    }	    ekey = &skey->key;	    kvno = server->entry.kvno;	}		ret = krb5_generate_random_keyblock(context, etype, &sessionkey);	if (ret)	    goto out;    }    /* check PAC if not cross realm and if there is one */    if (!cross_realm) {	Key *tkey;	ret = hdb_enctype2key(context, &krbtgt->entry, 			      krbtgt_etype, &tkey);	if(ret) {	    kdc_log(context, config, 0,		    "Failed to find key for krbtgt PAC check");	    goto out;	}	ret = check_PAC(context, config, client_principal, 			client, server, ekey, &tkey->key,			tgt, &rspac, &require_signedpath);	if (ret) {	    kdc_log(context, config, 0,		    "Verify PAC failed for %s (%s) from %s with %s",		    spn, cpn, from, krb5_get_err_text(context, ret));	    goto out;	}    }    /* also check the krbtgt for signature */    ret = check_KRB5SignedPath(context,			       config,			       krbtgt,			       tgt,			       &spp,			       require_signedpath);    if (ret) {	kdc_log(context, config, 0,		"KRB5SignedPath check failed for %s (%s) from %s with %s",		spn, cpn, from, krb5_get_err_text(context, ret));	goto out;    }    /*     *     */    ret = tgs_make_reply(context,			 config, 			 b, 			 client_principal,			 tgt, 			 ekey,			 &sessionkey,			 kvno,			 auth_data,			 server, 			 spn,			 client, 			 cp, 			 krbtgt, 			 krbtgt_etype,			 spp,			 &rspac,			 e_text,			 reply);	out:    free(spn);    free(cpn);	        krb5_data_free(&rspac);    krb5_free_keyblock_contents(context, &sessionkey);    if(server)	_kdc_free_ent(context, server);    if(client)	_kdc_free_ent(context, client);    if (client_principal && client_principal != cp)	krb5_free_principal(context, client_principal);    if (cp)	krb5_free_principal(context, cp);    if (sp)	krb5_free_principal(context, sp);    free_EncTicketPart(&adtkt);    return ret;}/* * */krb5_error_code_kdc_tgs_rep(krb5_context context, 	     krb5_kdc_configuration *config,	     KDC_REQ *req, 	     krb5_data *data,	     const char *from,	     struct sockaddr *from_addr,	     int datagram_reply){    AuthorizationData *auth_data = NULL;    krb5_error_code ret;    int i = 0;    const PA_DATA *tgs_req;    hdb_entry_ex *krbtgt = NULL;    krb5_ticket *ticket = NULL;    const char *e_text = NULL;    krb5_enctype krbtgt_etype = ETYPE_NULL;    time_t *csec = NULL;    int *cusec = NULL;    if(req->padata == NULL){	ret = KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */	kdc_log(context, config, 0,		"TGS-REQ from %s without PA-DATA", from);	goto out;    }        tgs_req = _kdc_find_padata(req, &i, KRB5_PADATA_TGS_REQ);    if(tgs_req == NULL){	ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;		kdc_log(context, config, 0, 		"TGS-REQ from %s without PA-TGS-REQ", from);	goto out;    }    ret = tgs_parse_request(context, config, 			    &req->req_body, tgs_req,			    &krbtgt,			    &krbtgt_etype,			    &ticket,			    &e_text,			    from, from_addr,			    &csec, &cusec,			    &auth_data);    if (ret) {	kdc_log(context, config, 0, 		"Failed parsing TGS-REQ from %s", from);	goto out;    }    ret = tgs_build_reply(context,			  config,			  req,			  &req->req_body,			  krbtgt,			  krbtgt_etype,			  ticket,			  data,			  from,			  &e_text,			  auth_data,			  from_addr,			  datagram_reply);    if (ret) {	kdc_log(context, config, 0, 		"Failed building TGS-REP to %s", from);	goto out;    }    /* */    if (datagram_reply && data->length > config->max_datagram_reply_length) {	krb5_data_free(data);	ret = KRB5KRB_ERR_RESPONSE_TOO_BIG;	e_text = "Reply packet too large";    }out:    if(ret && data->data == NULL){	krb5_mk_error(context,		      ret,		      NULL,		      NULL,		      NULL,		      NULL,		      csec,		      cusec,		      data);    }    free(csec);    free(cusec);    if (ticket)	krb5_free_ticket(context, ticket);    if(krbtgt)	_kdc_free_ent(context, krbtgt);    if (auth_data) {	free_AuthorizationData(auth_data);	free(auth_data);    }    return 0;}

⌨️ 快捷键说明

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