Ejemplo n.º 1
0
struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[])
{
  char svrnam[MAILTMPLEN],cltnam[MAILTMPLEN];
  krb5_context ctx;
  krb5_timestamp now;
  krb5_principal service;
  krb5_ccache ccache;
  krb5_error_code code;
  krb5_creds *crd = (krb5_creds *) memset (fs_get (sizeof (krb5_creds)),0,
						   sizeof (krb5_creds));
  struct passwd *ret = NIL;
  if (*pass) {			/* only if password non-empty */
				/* make service name */
    sprintf (svrnam,"%.80s@%.512s",
	     (char *) mail_parameters (NIL,GET_SERVICENAME,NIL),
	     tcp_serverhost ());
				/* make client name with principal */
    sprintf (cltnam,"%.80s/%.80s",pw->pw_name,
	     (char *) mail_parameters (NIL,GET_SERVICENAME,NIL));
				/* get a context */
    if (!krb5_init_context (&ctx)) {
				/* get time, client and server principals */
      if (!krb5_timeofday (ctx,&now) &&
	/* Normally, kerb_cp_svr_name (defined/set in env_unix.c) is NIL, so
	 * only the user name is used as a client principal.  A few sites want
	 * to have separate client principals for different services, but many
	 * other sites vehemently object...
	 */
	  !krb5_parse_name (ctx,kerb_cp_svr_name ? cltnam : pw->pw_name,
			    &crd->client) &&
	  !krb5_parse_name (ctx,svrnam,&service) &&
	  !krb5_build_principal_ext(ctx,&crd->server,
				    krb5_princ_realm (ctx,crd->client)->length,
				    krb5_princ_realm (ctx,crd->client)->data,
				    KRB5_TGS_NAME_SIZE,KRB5_TGS_NAME,
				    krb5_princ_realm (ctx,crd->client)->length,
				    krb5_princ_realm (ctx,crd->client)->data,
				    0)) {
				/* expire in 3 minutes */
	crd->times.endtime = now + (3 * 60);
	if (krb5_cc_resolve (ctx,"MEMORY:pwk",&ccache) ||
	    krb5_cc_initialize (ctx,ccache,crd->client)) ccache = 0;
	if (!krb5_get_in_tkt_with_password (ctx,NIL,NIL,NIL,NIL,pass,ccache,
					    crd,0) &&
	    !krb5_verify_init_creds (ctx,crd,service,0,ccache ? &ccache : 0,0))
	  ret = pw;
	krb5_free_creds (ctx,crd);/* flush creds and service principal */
	krb5_free_principal (ctx,service);
      }
      krb5_free_context (ctx);	/* don't need context any more */
    }
  }
  return ret;
}
Ejemplo n.º 2
0
/*******************************************************************
check on Kerberos authentication
********************************************************************/
static BOOL krb5_auth(char *this_user,char *password)
{
	krb5_data tgtname = {
		0,
		KRB5_TGS_NAME_SIZE,
	 	KRB5_TGS_NAME
 	};
	krb5_context kcontext;
	krb5_principal kprinc;
	krb5_principal server;
	krb5_creds kcreds;
	int options = 0;
	krb5_address **addrs = (krb5_address **)0;
	krb5_preauthtype *preauth = NULL;
	krb5_keytab keytab = NULL;
	krb5_timestamp now;
	krb5_ccache ccache = NULL;
	int retval;
	char *name;

	if ( retval=krb5_init_context(&kcontext))
	{
		return(False);
	}

	if ( retval = krb5_timeofday(kcontext, &now) )
	{
		return(False);
	}

	if ( retval = krb5_cc_default(kcontext, &ccache) )
	{
		return(False);
	}
	
	if ( retval = krb5_parse_name(kcontext, this_user, &kprinc) )
	{
		return(False);
	}

	memset((char *)&kcreds, 0, sizeof(kcreds));

	kcreds.client = kprinc;
	
	if ((retval = krb5_build_principal_ext(kcontext, &server,
		krb5_princ_realm(kcontext, kprinc)->length,
		krb5_princ_realm(kcontext, kprinc)->data,
		tgtname.length,
		tgtname.data,
		krb5_princ_realm(kcontext, kprinc)->length,
		krb5_princ_realm(kcontext, kprinc)->data,
		0)))
	{
 		return(False);
	}

	kcreds.server = server;

	retval = krb5_get_in_tkt_with_password(kcontext,
		options,
		addrs,
		NULL,
		preauth,
		password,
		0,
		&kcreds,
		0);

	if ( retval )
	{
		return(False);
	}

	return(True);
}
Ejemplo n.º 3
0
static int krb5_auth(void *instance, REQUEST *request)
{
	rlm_krb5_t *inst = instance;
	int ret;
	
	static char tgs_name[] = KRB5_TGS_NAME;
	krb5_data tgtname = {
		0,
		KRB5_TGS_NAME_SIZE,
		tgs_name
	};
	
	krb5_creds kcreds;
	krb5_ccache ccache;
	
	/* MEMORY: + unsigned int (20) + NULL */
	char cache_name[28];

	krb5_context context = *(inst->context); /* copy data */
	const char *user, *pass;

	/*
	 *  We can only authenticate user requests which HAVE
	 *  a User-Name attribute.
	 */
	if (!request->username) {
		radlog(L_AUTH, "rlm_krb5: Attribute \"User-Name\" is required for authentication.");
		
		return RLM_MODULE_INVALID;
	}

	/*
	 *  We can only authenticate user requests which HAVE
	 *  a User-Password attribute.
	 */
	if (!request->password) {
		radlog(L_AUTH, "rlm_krb5: Attribute \"User-Password\" is required for authentication.");
		
		return RLM_MODULE_INVALID;
	}

	/*
	 *  Ensure that we're being passed a plain-text password,
	 *  and not anything else.
	 */
	if (request->password->attribute != PW_USER_PASSWORD) {
		radlog(L_AUTH, "rlm_krb5: Attribute \"User-Password\" is required for authentication.  Cannot use \"%s\".", request->password->name);
		
		return RLM_MODULE_INVALID;
	}

	user = request->username->vp_strvalue;
	pass = request->password->vp_strvalue;

	/*
	 *  Generate a unique cache_name.
	 */
	snprintf(cache_name, sizeof(cache_name), "MEMORY:%u", request->number);

	ret = krb5_cc_resolve(context, cache_name, &ccache);
	if (ret) {
		radlog(L_AUTH, "rlm_krb5: [%s] krb5_cc_resolve(): %s",
		       user, error_message(ret));
		       
		return RLM_MODULE_REJECT;
	}

	/*
	 *  Actually perform the authentication.
	 */
	memset((char *)&kcreds, 0, sizeof(kcreds));

	ret = krb5_parse_name(context, user, &kcreds.client);
	if (ret) {
		radlog(L_AUTH, "rlm_krb5: [%s] krb5_parse_name failed: %s",
		       user, error_message(ret));
		       
		return RLM_MODULE_REJECT;
	}

	ret = krb5_cc_initialize(context, ccache, kcreds.client);
	if (ret) {
		radlog(L_AUTH, "rlm_krb5: [%s] krb5_cc_initialize(): %s",
		       user, error_message(ret));
		       
		return RLM_MODULE_REJECT;
	}

	/*
	 *  MIT krb5 verification.
	 */
	ret = krb5_build_principal_ext(context, &kcreds.server,
			krb5_princ_realm(context, kcreds.client)->length,
			krb5_princ_realm(context, kcreds.client)->data,
			tgtname.length,
			tgtname.data,
			krb5_princ_realm(context, kcreds.client)->length,
			krb5_princ_realm(context, kcreds.client)->data,
			0);
	if (ret) {
		radlog(L_AUTH, "rlm_krb5: [%s] krb5_build_principal_ext failed: %s",
			user, error_message(ret));
		krb5_cc_destroy(context, ccache);
		
		return RLM_MODULE_REJECT;
	}

	ret = krb5_get_in_tkt_with_password(context, 0, NULL, NULL, NULL, pass,
					    ccache, &kcreds, 0);
	if (ret) {
		radlog(L_AUTH, "rlm_krb5: [%s] krb5_g_i_t_w_p failed: %s",
		       user, error_message(ret));
		krb5_free_cred_contents(context, &kcreds);
		krb5_cc_destroy(context, ccache);
		
		return RLM_MODULE_REJECT;
	}

	/*
	 *  Now verify the KDC's identity.
	 */
	ret = verify_krb5_tgt(context, inst, user, ccache);
	krb5_free_cred_contents(context, &kcreds);
	krb5_cc_destroy(context, ccache);
	
	return ret;
}