コード例 #1
0
ファイル: server.c プロジェクト: Noltari/UC3M
//Servicio de STAT.
bool_t stat_rpc_1_svc(char* byte, struct server_stat *data_out, struct svc_req *rqstp) {
	//Petición de estadísticas.
	struct sockaddr_in *client_addr = svc_getcaller(rqstp->rq_xprt);
	printf("s> %s:%d init stat\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port));

	//Respuesta.
	pthread_mutex_lock(&stats_mutex[0]);
	data_out->ping = htonl(stats[0]);
	pthread_mutex_unlock(&stats_mutex[0]);
	pthread_mutex_lock(&stats_mutex[1]);
	data_out->swap = htonl(stats[1]);
	pthread_mutex_unlock(&stats_mutex[1]);
	pthread_mutex_lock(&stats_mutex[2]);
	data_out->hash = htonl(stats[2]);
	pthread_mutex_unlock(&stats_mutex[2]);
	pthread_mutex_lock(&stats_mutex[3]);
	data_out->check = htonl(stats[3]);
	pthread_mutex_unlock(&stats_mutex[3]);
	pthread_mutex_lock(&stats_mutex[4]);
	data_out->stat = htonl(stats[4]);
	pthread_mutex_unlock(&stats_mutex[4]);

	//Resultado de stat.
	printf("s> %s:%d stat = %u %u %u %u %u\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), ntohl(data_out->ping), ntohl(data_out->swap), ntohl(data_out->hash), ntohl(data_out->check), ntohl(data_out->stat));

	//Contador de estadísticas.
	pthread_mutex_lock(&stats_mutex[4]);
	stats[4]++;
	pthread_mutex_unlock(&stats_mutex[4]);

	return TRUE;
}
コード例 #2
0
ファイル: daVarRpcProc.c プロジェクト: dkb208/simc_gfortran
int *davar_readmultiple_test_1(TESTNAMELIST *argp, CLIENT *clnt)
{   /* Code fragment to get client info */
    static int result;
    int i;
    daVarCallBackList *next,*this;

    TESTNAMELIST *argcopy;

    SVCXPRT *transp;
    struct sockaddr_in *sock,*sockcopy;

    /*  printf("IN davar_readmultiple_test_1\n");*/
    sock = (struct sockaddr_in *)
           svc_getcaller(((struct svc_req *) clnt)->rq_xprt);

    /* Copy the arguments */
    argcopy = (TESTNAMELIST *) malloc(sizeof(TESTNAMELIST));
    argcopy->test_condition = (char *) malloc(strlen(argp->test_condition)+1);
    strcpy(argcopy->test_condition, argp->test_condition);
    argcopy->max_time_wait = argp->max_time_wait;
    argcopy->max_event_wait = argp->max_event_wait;
    argcopy->prog = argp->prog;
    argcopy->vers = argp->vers;
    argcopy->NAMELISTP = (NAMELIST *) malloc(sizeof(NAMELIST));
    argcopy->NAMELISTP->NAMELIST_len = argp->NAMELISTP->NAMELIST_len;
    argcopy->NAMELISTP->NAMELIST_val =
        (char **) malloc(argp->NAMELISTP->NAMELIST_len*sizeof(char *));
    for(i=0; i<argp->NAMELISTP->NAMELIST_len; i++) {
        argcopy->NAMELISTP->NAMELIST_val[i] = (char *)
                                              malloc(strlen(argp->NAMELISTP->NAMELIST_val[i])+1);
        strcpy(argcopy->NAMELISTP->NAMELIST_val[i]
               ,argp->NAMELISTP->NAMELIST_val[i]);
    }
    /* Copy the socket */
    sockcopy = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
    bzero(sockcopy,sizeof(struct sockaddr_in));
    bcopy(sock,sockcopy,sizeof(struct sockaddr_in));

    /*  printf("Socket copied\n");*/
    next = thCallBackListP;
    this = thCallBackListP = (daVarCallBackList *)
                             malloc(sizeof(daVarCallBackList));
    this->sock_in = sockcopy;         /* Actually need to copy structure */
    this->list = argcopy;
    this->start_time = time(0);	/* Record when request came in */
    this->next = next;


#if 0
    hp = (struct hostent *)
         gethostbyaddr((char *)&sockcopy->sin_addr, sizeof(sockcopy->sin_addr),AF_INET);
    printf("%s %s\n", inet_ntoa(sockcopy->sin_addr), hp->h_name);
#endif

    result = S_SUCCESS;
    return(&result);
}
コード例 #3
0
ファイル: server.c プロジェクト: Noltari/UC3M
//Servicio de QUIT.
bool_t quit_rpc_1_svc(char* byte, char *result, struct svc_req *rqstp) {
	//Petición de salida.
	struct sockaddr_in *client_addr = svc_getcaller(rqstp->rq_xprt);
	printf("s> %s:%d quit\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port));

	*result = CODE_QUIT;

	return TRUE;
}
コード例 #4
0
ファイル: server.c プロジェクト: Noltari/UC3M
//Servicio de CHECK.
bool_t check_rpc_1_svc(struct check_pet *data_in, struct check_res *data_out, struct svc_req *rqstp) {
	//Petición check.
	struct sockaddr_in *client_addr = svc_getcaller(rqstp->rq_xprt);
	if(ntohl(data_in->iter) == 0) {
		//Contador de estadísticas.
		pthread_mutex_lock(&stats_mutex[3]);
		stats[3]++;
		pthread_mutex_unlock(&stats_mutex[3]);

		printf("s> %s:%d init check %u %u\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), ntohl(data_in->total_length), ntohl(data_in->hash_client));
	}

	//Copiamos información de la petición a la respuesta.
	data_out->iter = data_in->iter;
	data_out->total_iter = data_in->total_iter;
	data_out->total_length = data_in->total_length;
	data_out->hash_client = data_in->hash_client;

	//Hash chars.
	unsigned int i, hash_local = 0;
	for(i = 0; i < ntohl(data_in->text_length); i++) {
		hash_local = hash_local + data_in->text[i] % HASH_MOD;
	}

	//Actualizamos el hash.
	data_out->hash_local = htonl(hash_local);
	data_out->hash = htonl((hash_local + ntohl(data_in->hash)) % HASH_MOD);

	//(DEBUG) Información sobre la iteración del check.
	if(DEBUG) {
		printf("s> %s:%d check iter[%d] %u (%u)\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), ntohl(data_in->iter), hash_local, ntohl(data_in->text_length));
	}

	//Resultado de check.
	if(ntohl(data_out->iter) == ntohl(data_out->total_iter) - 1) {
		if(data_out->hash == data_out->hash_client) {
			data_out->check = CHECK_OK;
		}
		else {
			data_out->check = CHECK_FAIL;
		}

		char *check_string;
		if(data_out->check == CHECK_OK) {
			check_string = CHECK_STRING_OK;
		}
		else if(data_out->check == CHECK_FAIL) {
			check_string = CHECK_STRING_FAIL;
		}

		printf("s> %s:%d check = %s\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), check_string);
	}

	return TRUE;
}
コード例 #5
0
ファイル: yp.c プロジェクト: Eastsideboy/freebsd
int
yp_check(struct svc_req *req)
{
	struct sockaddr_in	*caller;

	caller = svc_getcaller(req->rq_xprt);
	/*
	 * We might want to know who we allow here.
	 */
	return (0);
}
コード例 #6
0
ファイル: ldm4_svc.c プロジェクト: PatrickHildreth-NOAA/LDM
/*
 * Handles incoming LDM-4 RPC NULLPROC requests (only).  This method is 
 * directly and repeatedly invoked by the RPC layer after svc_run(3NSL) is 
 * invoked.
 *
 * rqstp        The RPC request.
 * transp       The server-side RPC transport.
 */
void
ldmprog_4(struct svc_req *rqstp, register SVCXPRT *transp)
{
    if (rqstp->rq_proc == 0) {                          /* NULLPROC */
        unotice("ldmprog_4: ldmping from %s",
            hostbyaddr((struct sockaddr_in*)svc_getcaller(transp)));
        (void)svc_sendreply(transp, (xdrproc_t) xdr_void, (char *)NULL);
    }
    else {
        svcerr_noproc(transp);
    }
}
コード例 #7
0
ファイル: rpc_svc_1.c プロジェクト: shubmit/shub-ltp
char *svc_getcaller_test(union u_argument *inVar, SVCXPRT *transp)
{
	//In this function we test svc_getcaller function basically (simple call)
	struct sockaddr_in *sa = NULL;
	static int result;

	sa = svc_getcaller (transp);
	//If the result is not NULL we consider that function call succeeds
	//so returns 0 (PASS)
	result = (sa != NULL) ? 0 : 1;
	return (char *)&result;
}
コード例 #8
0
ファイル: procs.c プロジェクト: ajinkya93/OpenBSD
void *
nlm4_granted_msg_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
{
	static nlm4_res result;

	if (debug_level)
		log_from_addr("nlm4_granted_msg", rqstp);

	result.cookie = arg->cookie;
	result.stat.stat = nlm4_granted;
	transmit4_result(NLM4_GRANTED_RES, &result, svc_getcaller(rqstp->rq_xprt));
	return NULL;
}
コード例 #9
0
ファイル: server.c プロジェクト: Noltari/UC3M
//Servicio de SWAP.
bool_t swap_rpc_1_svc(struct swap_data* data_in, struct swap_data *data_out, struct svc_req *rqstp) {
	//Petición de intercambio de letras.
	struct sockaddr_in *client_addr = svc_getcaller(rqstp->rq_xprt);
	if(ntohl(data_in->iter) == 0) {
		//Contador de estadísticas.
		pthread_mutex_lock(&stats_mutex[1]);
		stats[1]++;
		pthread_mutex_unlock(&stats_mutex[1]);

		printf("s> %s:%d init swap %u\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), ntohl(data_in->total_length));
	}

	//Copiamos información de la petición a la respuesta.
	data_out->iter = data_in->iter;
	data_out->total_iter = data_in->total_iter;
	data_out->total_length = data_in->total_length;
	data_out->text_length = data_in->text_length;

	//Swap chars.
	unsigned int i, swapped_local = 0;
	for(i = 0; i < ntohl(data_in->text_length); i++) {
		if(data_in->text[i] != tolower(data_in->text[i])) {
			data_out->text[i] = tolower(data_in->text[i]);
			swapped_local++;
		}
		else if(data_in->text[i] != toupper(data_in->text[i])) {
			data_out->text[i] = toupper(data_in->text[i]);
			swapped_local++;
		}
		else {
			data_out->text[i] = data_in->text[i];
		}
	}

	//Actualizamos el número de swaps.
	data_out->swapped_local = htonl(swapped_local);
	data_out->swapped = htonl(swapped_local + ntohl(data_in->swapped));

	//(DEBUG) Información sobre la iteración del swap.
	if(DEBUG) {
		printf("s> %s:%d swap iter[%d] %u/%u\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), ntohl(data_in->iter), swapped_local, ntohl(data_in->text_length));
	}

	//Resultado de swap.
	if(ntohl(data_out->iter) == ntohl(data_out->total_iter) - 1) {
		printf("s> %s:%d swap = %u\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), ntohl(data_out->swapped));
	}

	return TRUE;
}
コード例 #10
0
ファイル: lock_proc.c プロジェクト: AhmadTux/DragonFlyBSD
void *
nlm_granted_msg_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
{
	static nlm_res res;

	if (debug_level)
		log_from_addr("nlm_granted_msg", rqstp);

	res.cookie = arg->cookie;
	res.stat.stat = nlm_granted;
	transmit_result(NLM_GRANTED_RES, &res,
	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
	return (NULL);
}
コード例 #11
0
ファイル: procs.c プロジェクト: ajinkya93/OpenBSD
void *
nlm4_unlock_msg_4_svc(nlm4_unlockargs *arg, struct svc_req *rqstp)
{
	static nlm4_res result;

	if (debug_level)
		log_from_addr("nlm4_unlock_msg", rqstp);

	result.stat.stat = unlock(&arg->alock, LOCK_V4);
	result.cookie = arg->cookie;

	transmit4_result(NLM4_UNLOCK_RES, &result, svc_getcaller(rqstp->rq_xprt));
	return NULL;
}
コード例 #12
0
ファイル: procs.c プロジェクト: ajinkya93/OpenBSD
void *
nlm_test_msg_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
{
	nlm_testres result;
	static char dummy;
	struct sockaddr_in *addr;
	CLIENT *cli;
	int success;
	struct timeval timeo;
	struct nlm4_lock arg4;
	struct nlm4_holder *holder;

	nlmtonlm4(&arg->alock, &arg4);

	if (debug_level)
		log_from_addr("nlm_test_msg", rqstp);

	holder = testlock(&arg4, 0);

	result.cookie = arg->cookie;
	if (holder == NULL) {
		result.stat.stat = nlm_granted;
	} else {
		result.stat.stat = nlm_denied;
		memcpy(&result.stat.nlm_testrply_u.holder, holder,
		    sizeof(struct nlm_holder));
		result.stat.nlm_testrply_u.holder.l_offset =
		    (unsigned int)holder->l_offset;
		result.stat.nlm_testrply_u.holder.l_len =
		    (unsigned int)holder->l_len;
	}

	/*
	 * nlm_test has different result type to the other operations, so
	 * can't use transmit_result() in this case
	 */
	addr = svc_getcaller(rqstp->rq_xprt);
	if ((cli = get_client(addr, NLM_VERS)) != NULL) {
		/* No timeout - not expecting response */
		timerclear(&timeo);

		success = clnt_call(cli, NLM_TEST_RES, xdr_nlm_testres,
		    &result, xdr_void, &dummy, timeo);

		if (debug_level > 2)
			syslog(LOG_DEBUG, "clnt_call returns %d", success);
	}
	return NULL;
}
コード例 #13
0
ファイル: procs.c プロジェクト: ajinkya93/OpenBSD
/*
 * Purpose:	Log name of function called and source address
 * Returns:	Nothing
 * Notes:	Extracts the source address from the transport handle
 *		passed in as part of the called procedure specification
 */
static void 
log_from_addr(char *fun_name, struct svc_req *req)
{
	struct	sockaddr_in *addr;
	struct	hostent *host;
	char	hostname_buf[HOST_NAME_MAX+1];

	addr = svc_getcaller(req->rq_xprt);
	host = gethostbyaddr((char *) &(addr->sin_addr), addr->sin_len, AF_INET);
	if (host)
		strlcpy(hostname_buf, host->h_name, sizeof(hostname_buf));
	else
		strlcpy(hostname_buf, inet_ntoa(addr->sin_addr),
		    sizeof hostname_buf);
	syslog(LOG_DEBUG, "%s from %s", fun_name, hostname_buf);
}
コード例 #14
0
ファイル: procs.c プロジェクト: ajinkya93/OpenBSD
void *
nlm_unlock_msg_1_svc(nlm_unlockargs *arg, struct svc_req *rqstp)
{
	static nlm_res result;
	struct nlm4_lock arg4;

	nlmtonlm4(&arg->alock, &arg4);

	if (debug_level)
		log_from_addr("nlm_unlock_msg", rqstp);

	result.stat.stat = unlock(&arg4, 0);
	result.cookie = arg->cookie;

	transmit_result(NLM_UNLOCK_RES, &result, svc_getcaller(rqstp->rq_xprt));
	return NULL;
}
コード例 #15
0
ファイル: procs.c プロジェクト: ajinkya93/OpenBSD
void *
nlm4_cancel_msg_4_svc(nlm4_cancargs *arg, struct svc_req *rqstp)
{
	static nlm4_res result;

	if (debug_level)
		log_from_addr("nlm4_cancel_msg", rqstp);

	result.cookie = arg->cookie;
	/*
	 * Since at present we never return 'nlm_blocked', there can never be
	 * a lock to cancel, so this call always fails.
	 */
	result.stat.stat = unlock(&arg->alock, LOCK_CANCEL | LOCK_V4);
	transmit4_result(NLM4_CANCEL_RES, &result, svc_getcaller(rqstp->rq_xprt));

	return NULL;
}
コード例 #16
0
ファイル: pmap_check.c プロジェクト: Einheri/wl500g
int
check_setunset(SVCXPRT *xprt, SVCXPRT *ludp_xprt, SVCXPRT *ltcp_xprt,
	       u_long  proc, u_long  prog, u_long  port)
{
    struct sockaddr_in *addr = svc_getcaller(xprt);

    if (xprt != ludp_xprt && xprt != ltcp_xprt) {
#ifdef HOSTS_ACCESS
	(void) good_client(addr);		/* because of side effects */
#endif
	log_bad_owner(addr, proc, prog);
	return (FALSE);
    }
    if (port && !check_privileged_port(addr, proc, prog, port))
	return (FALSE);
    if (verboselog)
	log_client(addr, proc, prog);
    return (TRUE);
}
コード例 #17
0
ファイル: auth_clnt.c プロジェクト: ph1ee/nfs-server-2.3-5
/*
 * For an RPC request, look up the NFS client info along with the
 * list of directories exported to that client.
 */
nfs_client *
auth_clnt(struct svc_req *rqstp)
{
	nfs_client *cp = NULL;
	struct in_addr addr = svc_getcaller(rqstp->rq_xprt)->sin_addr;

	/* Get the client and list of exports */
	if ((cp = auth_clientbyaddr(addr)) != NULL)
		return cp;

	/* We don't know you */
	if (trace_spoof) {
		dbg_printf(__FILE__, __LINE__, L_ERROR,
			   "Unauthorized access by NFS client %s.\n",
			   inet_ntoa(addr));
	}

	return (NULL);
}
コード例 #18
0
ファイル: server.c プロジェクト: Noltari/UC3M
//Servicio de PING.
bool_t ping_rpc_1_svc(char* byte, char *result, struct svc_req *rqstp) {
	//Contador de estadísticas.
	pthread_mutex_lock(&stats_mutex[0]);
	stats[0]++;
	pthread_mutex_unlock(&stats_mutex[0]);

	//Petición de ping.
	struct sockaddr_in *client_addr = svc_getcaller(rqstp->rq_xprt);
	printf("s> %s:%d ping\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port));

	if(*byte == CODE_PING) {
		*result = CODE_PING;
		return TRUE;
	}
	else {
		*result = CODE_ERROR;
		return FALSE;
	}
}
コード例 #19
0
ファイル: auth_clnt.c プロジェクト: ph1ee/nfs-server-2.3-5
nfs_mount *
auth_path(nfs_client * cp, struct svc_req * rqstp, char *path)
{
	nfs_mount *mp;

	/* Check if the specified client is permitted to access this */
	if ((mp = auth_match_mount(cp, path)) == NULL) {
		if (cp->flags != 0 || trace_spoof) {
			dbg_printf(__FILE__, __LINE__, L_ERROR,
				   "NFS client %s tried to access %s\n",
				   cp->clnt_name, path);
		}
		return NULL;
	}

	/* Check request originated on a privileged port. */
	if (!allow_non_root && mp->o.secure_port
	    && !SECURE_PORT(svc_getcaller(rqstp->rq_xprt)->sin_port)) {
		dbg_printf(__FILE__, __LINE__, L_ERROR,
			   "NFS request from %s originated on insecure port, %s\n",
			   cp->clnt_name, "psychoanalysis suggested");
		return (NULL);
	}

	if (log_level_enabled(D_AUTH)) {
		dbg_printf(__FILE__, __LINE__, D_AUTH,
			   "auth_path(%s): mount point %s, (%s%s%s%s%s)\n",
			   path, mp->path,
			   mp->o.all_squash ? "all_squash " : (mp->o.
							       root_squash ?
							       "root_squash "
							       : ""),
			   (mp->o.uidmap == map_daemon) ? "uidmap " : "",
			   mp->o.secure_port ? "secure " : "insecure ",
			   mp->o.link_relative ? "linkrel " : "",
			   mp->o.read_only ? "ro" : "rw");
	}

	return mp;
}
コード例 #20
0
ファイル: procs.c プロジェクト: ajinkya93/OpenBSD
void *
nlm_lock_msg_1_svc(nlm_lockargs *arg, struct svc_req *rqstp)
{
	static nlm_res result;
	struct nlm4_lockargs arg4;

	nlmtonlm4(&arg->alock, &arg4.alock);
	arg4.cookie = arg->cookie;
	arg4.block = arg->block;
	arg4.exclusive = arg->exclusive;
	arg4.reclaim = arg->reclaim;
	arg4.state = arg->state;

	if (debug_level)
		log_from_addr("nlm_lock_msg", rqstp);

	result.cookie = arg->cookie;
	result.stat.stat = getlock(&arg4, rqstp, LOCK_ASYNC | LOCK_MON);
	transmit_result(NLM_LOCK_RES, &result, svc_getcaller(rqstp->rq_xprt));

	return NULL;
}
コード例 #21
0
ファイル: server.c プロジェクト: Noltari/UC3M
//Servicio de HASH.
bool_t hash_rpc_1_svc(struct hash_pet *data_in, struct hash_res *data_out, struct svc_req *rqstp) {
	//Petición de hash.
	struct sockaddr_in *client_addr = svc_getcaller(rqstp->rq_xprt);
	if(ntohl(data_in->iter) == 0) {
		//Contador de estadísticas.
		pthread_mutex_lock(&stats_mutex[2]);
		stats[2]++;
		pthread_mutex_unlock(&stats_mutex[2]);

		printf("s> %s:%d init hash %u\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), ntohl(data_in->total_length));
	}

	//Copiamos información de la petición a la respuesta.
	data_out->iter = data_in->iter;
	data_out->total_iter = data_in->total_iter;
	data_out->total_length = data_in->total_length;

	//Hash chars.
	unsigned int i, hash_local = 0;
	for(i = 0; i < ntohl(data_in->text_length); i++) {
		hash_local = hash_local + data_in->text[i] % HASH_MOD;
	}

	//Actualizamos el hash.
	data_out->hash_local = htonl(hash_local);
	data_out->hash = htonl((hash_local + ntohl(data_in->hash)) % HASH_MOD);

	//(DEBUG) Información sobre la iteración del hash.
	if(DEBUG) {
		printf("s> %s:%d hash iter[%d] %u (%u)\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), ntohl(data_in->iter), hash_local, ntohl(data_in->text_length));
	}

	//Resultado de hash.
	if(ntohl(data_out->iter) == ntohl(data_out->total_iter) - 1) {
		printf("s> %s:%d hash = %u\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), ntohl(data_out->hash));
	}

	return TRUE;
}
コード例 #22
0
ファイル: can_server.c プロジェクト: raph38130/rplgm
float * 
lirecan_1_svc(int *argp, struct svc_req *rqstp)
{
	static float  result;
	struct sockaddr_in *adr;
	int ipad;
	
	/*
	 * insert server code here
	 */
	printf("accès à la voie n° %d\n",*argp);
	adr=svc_getcaller(rqstp->rq_xprt);
	ipad=ntohl(adr->sin_addr.s_addr);
	
	printf("par %d.%d.%d.%d\n",	(ipad >> 24) & 0xFF, 
					(ipad >> 16) & 0xFF,
					(ipad >> 8)  & 0xFF,
					(ipad )      & 0xFF);
	
	result=3.1415927;
	
	return &result;
}
コード例 #23
0
int resolv_req(bool *fwding, CLIENT **client, int *pid, char *tp,
		SVCXPRT *xprt, struct ypreq_key *req, char *map)
{
	enum clnt_stat stat;
	struct timeval tv;
	struct ypfwdreq_key4 fwd_req4;
	struct ypfwdreq_key6 fwd_req6;
	struct in6_addr in6;
	int byname, byaddr;
	int byname_v6, byaddr_v6;
#ifdef TDRPC
	struct sockaddr_in *addrp;
#else
	struct netbuf *nb;
	char *uaddr;
	char *cp;
	int i;
	sa_family_t caller_af = AF_UNSPEC;
	struct sockaddr_in *sin4;
	struct sockaddr_in6 *sin6;
#endif


	if (! *fwding)
		return (FALSE);

	byname = strcmp(map, "hosts.byname") == 0;
	byaddr = strcmp(map, "hosts.byaddr") == 0;
	byname_v6 = strcmp(map, "ipnodes.byname") == 0;
	byaddr_v6 = strcmp(map, "ipnodes.byaddr") == 0;
	if ((!byname && !byaddr && !byname_v6 && !byaddr_v6) ||
				req->keydat.dsize == 0 ||
				req->keydat.dptr[0] == '\0' ||
				!isascii(req->keydat.dptr[0]) ||
				!isgraph(req->keydat.dptr[0])) {
		/* default status is YP_NOKEY */
		return (FALSE);
	}

#ifdef TDRPC
	fwd_req4.map = map;
	fwd_req4.keydat = req->keydat;
	fwd_req4.xid = svc_getxid(xprt);
	addrp = svc_getcaller(xprt);
	fwd_req4.ip = addrp->sin_addr.s_addr;
	fwd_req4.port = addrp->sin_port;
#else
	/*
	 * In order to tell if we have an IPv4 or IPv6 caller address,
	 * we must know that nb->buf is a (sockaddr_in *) or a
	 * (sockaddr_in6 *). Hence, we might as well dispense with the
	 * conversion to uaddr and parsing of same that this section
	 * of the code previously involved itself in.
	 */
	nb = svc_getrpccaller(xprt);
	if (nb != 0)
		caller_af = ((struct sockaddr_storage *)nb->buf)->ss_family;

	if (caller_af == AF_INET6) {
		fwd_req6.map = map;
		fwd_req6.keydat = req->keydat;
		fwd_req6.xid = svc_getxid(xprt);
		sin6 = (struct sockaddr_in6 *)nb->buf;
		fwd_req6.addr = (uint32_t *)&in6;
		memcpy(fwd_req6.addr, sin6->sin6_addr.s6_addr, sizeof (in6));
		fwd_req6.port = ntohs(sin6->sin6_port);
	} else if (caller_af == AF_INET) {
		fwd_req4.map = map;
		fwd_req4.keydat = req->keydat;
		fwd_req4.xid = svc_getxid(xprt);
		sin4 = (struct sockaddr_in *)nb->buf;
		fwd_req4.ip = ntohl(sin4->sin_addr.s_addr);
		fwd_req4.port = ntohs(sin4->sin_port);
	} else {
		syslog(LOG_ERR, "unknown caller IP address family %d",
			caller_af);
		return (FALSE);
	}
#endif

	/* Restart resolver if it died. (possible overkill) */
	if (kill(*pid, 0)) {
		syslog(LOG_INFO,
		"Restarting resolv server: old one (pid %d) died.\n", *pid);
		if (*client != NULL)
			clnt_destroy (*client);
		setup_resolv(fwding, pid, client, tp, 0 /* transient p# */);
		if (!*fwding) {
			syslog(LOG_ERR,
			"can't restart resolver: ending resolv service.\n");
			return (FALSE);
		}
	}

	/* may need to up timeout */
	tv.tv_sec = 10; tv.tv_usec = 0;
	if (caller_af == AF_INET6) {
		stat = clnt_call(*client, YPDNSPROC6, xdr_ypfwdreq_key6,
					(char *)&fwd_req6, xdr_void, 0, tv);
	} else {
		stat = clnt_call(*client, YPDNSPROC4, xdr_ypfwdreq_key4,
					(char *)&fwd_req4, xdr_void, 0, tv);
	}
	if (stat == RPC_SUCCESS) /* expected */
		return (TRUE);

	else { /* Over kill error recovery */
		/* make one attempt to restart service before turning off */
		syslog(LOG_INFO,
			"Restarting resolv server: old one not responding.\n");

		if (!kill(*pid, 0))
			kill (*pid, SIGINT); /* cleanup old one */

		if (*client != NULL)
			clnt_destroy (*client);
		setup_resolv(fwding, pid, client, tp, 0 /* transient p# */);
		if (!*fwding) {
			syslog(LOG_ERR,
			"can't restart resolver: ending resolv service.\n");
			return (FALSE);
		}

		if (caller_af == AF_INET6) {
			stat = clnt_call(*client, YPDNSPROC6, xdr_ypfwdreq_key6,
					(char *)&fwd_req6, xdr_void, 0, tv);
		} else {
			stat = clnt_call(*client, YPDNSPROC4, xdr_ypfwdreq_key4,
					(char *)&fwd_req4, xdr_void, 0, tv);
		}
		if (stat == RPC_SUCCESS) /* expected */
			return (TRUE);
		else {
			/* no more restarts */
			clnt_destroy (*client);
			*fwding = FALSE; /* turn off fwd'ing */
			syslog(LOG_ERR,
		"restarted resolver not responding: ending resolv service.\n");
			return (FALSE);
		}
	}
}
コード例 #24
0
ファイル: pmap_svc.c プロジェクト: ryo/netbsd-src
static bool_t
pmapproc_change(struct svc_req *rqstp, SVCXPRT *xprt, unsigned long op)
{
	struct pmap reg;
	RPCB rpcbreg;
	long ans;
	struct sockcred *sc;
	char uidbuf[32];

	if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (char *)&reg)) {
		svcerr_decode(xprt);
		return (FALSE);
	}

#ifdef RPCBIND_DEBUG
	if (debugging)
		fprintf(stderr, "%s request for (%lu, %lu) : ",
		    op == PMAPPROC_SET ? "PMAP_SET" : "PMAP_UNSET",
		    reg.pm_prog, reg.pm_vers);
#endif

	if (!check_access(xprt, op, &reg, PMAPVERS)) {
		svcerr_weakauth(xprt);
		return FALSE;
	}

	(void)svc_getcaller(xprt);
	sc = __svc_getcallercreds(xprt);

	/*
	 * Can't use getpwnam here. We might end up calling ourselves
	 * and looping.
	 */
	if (sc == NULL)
		rpcbreg.r_owner = __UNCONST(rpcbind_unknown);
	else if (sc->sc_uid == 0)
		rpcbreg.r_owner = __UNCONST(rpcbind_superuser);
	else {
		/* r_owner will be strdup-ed later */
		snprintf(uidbuf, sizeof uidbuf, "%d", sc->sc_uid);
		rpcbreg.r_owner = uidbuf;
	}

	rpcbreg.r_prog = reg.pm_prog;
	rpcbreg.r_vers = reg.pm_vers;

	if (op == PMAPPROC_SET) {
		char buf[32];

		snprintf(buf, sizeof(buf), "0.0.0.0.%d.%d",
		    (int)((reg.pm_port >> 8) & 0xff),
		    (int)(reg.pm_port & 0xff));
		rpcbreg.r_addr = buf;
		if (reg.pm_prot == IPPROTO_UDP) {
			rpcbreg.r_netid = __UNCONST(udptrans);
		} else if (reg.pm_prot == IPPROTO_TCP) {
			rpcbreg.r_netid = __UNCONST(tcptrans);
		} else {
			ans = FALSE;
			goto done_change;
		}
		ans = map_set(&rpcbreg, rpcbreg.r_owner);
	} else if (op == PMAPPROC_UNSET) {
コード例 #25
0
/**
 * Returns an identifier of the remote client.
 *
 * @param[in] rqstp  Client-request object.
 */
const char*
rpc_getClientId(
    struct svc_req* const rqstp)
{
    return hostbyaddr(svc_getcaller(rqstp->rq_xprt));
}
コード例 #26
0
enum auth_stat gssrpc__svcauth_gssapi(
     register struct svc_req *rqst,
     register struct rpc_msg *msg,
     bool_t *no_dispatch)
{
     XDR xdrs;
     auth_gssapi_creds creds;
     auth_gssapi_init_arg call_arg;
     auth_gssapi_init_res call_res;
     gss_buffer_desc output_token, in_buf, out_buf;
     gss_cred_id_t server_creds;
     struct gss_channel_bindings_struct bindings, *bindp;
     OM_uint32 gssstat, minor_stat, time_rec;
     struct opaque_auth *cred, *verf;
     svc_auth_gssapi_data *client_data;
     int i;
     enum auth_stat ret;
     OM_uint32 ret_flags;
     uint32_t seq_num;

     PRINTF(("svcauth_gssapi: starting\n"));
     
     /* clean up expired entries */
     clean_client();

     /* use AUTH_NONE until there is a client_handle */
     rqst->rq_xprt->xp_auth = &svc_auth_none;
     
     memset((char *) &call_res, 0, sizeof(call_res));
     creds.client_handle.length = 0;
     creds.client_handle.value = NULL;
     
     cred = &msg->rm_call.cb_cred;
     verf = &msg->rm_call.cb_verf;
     
     if (cred->oa_length == 0) {
	  PRINTF(("svcauth_gssapi: empty creds, failing\n"));
	  LOG_MISCERR("empty client credentials");
	  ret = AUTH_BADCRED;
	  goto error;
     }

     PRINTF(("svcauth_gssapi: decoding credentials\n"));
     xdrmem_create(&xdrs, cred->oa_base, cred->oa_length, XDR_DECODE); 
     memset((char *) &creds, 0, sizeof(creds));
     if (! xdr_authgssapi_creds(&xdrs, &creds)) {
	  PRINTF(("svcauth_gssapi: failed decoding creds\n"));
	  LOG_MISCERR("protocol error in client credentials");
	  xdr_free(xdr_authgssapi_creds, &creds);
	  XDR_DESTROY(&xdrs);
	  ret = AUTH_BADCRED;
	  goto error;
     }
     XDR_DESTROY(&xdrs);

     PRINTF(("svcauth_gssapi: got credentials, version %d, client_handle len %d\n",
	     creds.version, (int) creds.client_handle.length));

     if (creds.version != 2) {
 	  PRINTF(("svcauth_gssapi: bad credential version\n"));
 	  LOG_MISCERR("unsupported client credentials version");
 	  ret = AUTH_BADCRED;
 	  goto error;
     }

#ifdef DEBUG_GSSAPI
     if (svc_debug_gssapi) {
	  if (creds.auth_msg && rqst->rq_proc == AUTH_GSSAPI_EXIT) {
	       PRINTF(("svcauth_gssapi: GSSAPI_EXIT, cleaning up\n"));
	       svc_sendreply(rqst->rq_xprt, xdr_void, NULL);
	       xdr_free(xdr_authgssapi_creds, &creds);
	       cleanup();
	       exit(0);
	  }
     }
#endif
	  
     /*
      * If this is an auth_msg and proc is GSSAPI_INIT, then create a
      * client handle for this client.  Otherwise, look up the
      * existing handle.
      */
     if (creds.auth_msg && rqst->rq_proc == AUTH_GSSAPI_INIT) {
	  if (creds.client_handle.length != 0) {
	       PRINTF(("svcauth_gssapi: non-empty handle on GSSAPI_INIT\n"));
	       LOG_MISCERR("protocol error in client handle");
	       ret = AUTH_FAILED;
	       goto error;
	  }
	       
	  PRINTF(("svcauth_gssapi: GSSAPI_INIT, creating client.\n"));
	  
	  client_data = create_client();
	  if (client_data == NULL) {
	       PRINTF(("svcauth_gssapi: create_client failed\n"));
	       LOG_MISCERR("internal error creating client record");
	       ret = AUTH_FAILED;
	       goto error;
	  }
     } else {
	  if (creds.client_handle.length == 0) {
	       PRINTF(("svcauth_gssapi: expected non-empty creds\n"));
	       LOG_MISCERR("protocol error in client credentials");
	       ret = AUTH_FAILED;
	       goto error;
	  }
	  
	  PRINTF(("svcauth_gssapi: incoming client_handle %d, len %d\n", 
		  *((uint32_t *) creds.client_handle.value),
		  (int) creds.client_handle.length));

	  client_data = get_client(&creds.client_handle);
	  if (client_data == NULL) {
	       PRINTF(("svcauth_gssapi: client_handle lookup failed\n"));
	       LOG_MISCERR("invalid client handle received");
	       ret = AUTH_BADCRED;
	       goto error;
	  }
	  PRINTF(("svcauth_gssapi: client_handle lookup succeeded\n"));
     }

     /* any response we send will use client_handle, so set it now */
     call_res.client_handle.length = sizeof(client_data->key);
     call_res.client_handle.value = (char *) &client_data->key;
     
     /* mark this call as using AUTH_GSSAPI via client_data's SVCAUTH */
     rqst->rq_xprt->xp_auth = &client_data->svcauth;

     if (client_data->established == FALSE) {
	  PRINTF(("svcauth_gssapi: context is not established\n"));

	  if (creds.auth_msg == FALSE) {
	       PRINTF(("svcauth_gssapi: expected auth_msg TRUE\n"));
	       LOG_MISCERR("protocol error on incomplete connection");
	       ret = AUTH_REJECTEDCRED;
	       goto error;
	  }

	  /*
	   * If the context is not established, then only GSSAPI_INIT
	   * and _CONTINUE requests are valid.
	   */
	  if (rqst->rq_proc != AUTH_GSSAPI_INIT && rqst->rq_proc !=
	      AUTH_GSSAPI_CONTINUE_INIT) {
	       PRINTF(("svcauth_gssapi: unacceptable procedure %d\n",
		       rqst->rq_proc));
	       LOG_MISCERR("protocol error on incomplete connection");
	       ret = AUTH_FAILED;
	       goto error;
	  }

	  /* call is for us, deserialize arguments */
	  memset(&call_arg, 0, sizeof(call_arg));
	  if (! svc_getargs(rqst->rq_xprt, xdr_authgssapi_init_arg,
			    &call_arg)) {
	       PRINTF(("svcauth_gssapi: cannot decode args\n"));
	       LOG_MISCERR("protocol error in procedure arguments");
	       ret = AUTH_BADCRED;
	       goto error;
	  }

	  /*
	   * Process the call arg version number.
	   * 
	   * Set the krb5_gss backwards-compatibility mode based on client
	   * version.  This controls whether the AP_REP message is
	   * encrypted with the session key (version 2+, correct) or the
	   * session subkey (version 1, incorrect).  This function can
	   * never fail, so we don't bother checking its return value.
	   */
	  switch (call_arg.version) {
	  case 1:
	  case 2:
	       LOG_MISCERR("Warning: Accepted old RPC protocol request");
	       call_res.version = 1;
	       break;
	  case 3:
	  case 4:
	       /* 3 and 4 are essentially the same, don't bother warning */
	       call_res.version = call_arg.version;
	       break;
	  default:
	       PRINTF(("svcauth_gssapi: bad GSSAPI_INIT version\n"));
	       LOG_MISCERR("unsupported GSSAPI_INIT version");
	       ret = AUTH_BADCRED;
	       goto error;
	  }

#ifdef GSS_BACKWARD_HACK
	  krb5_gss_set_backward_mode(&minor_stat, call_arg.version == 1);
#endif

	  if (call_arg.version >= 3) {
	       memset(&bindings, 0, sizeof(bindings));
	       bindings.application_data.length = 0;
	       bindings.initiator_addrtype = GSS_C_AF_INET;
	       bindings.initiator_address.length = 4;
	       bindings.initiator_address.value =
		    &svc_getcaller(rqst->rq_xprt)->sin_addr.s_addr;

	       if (rqst->rq_xprt->xp_laddrlen > 0) {
		    bindings.acceptor_addrtype = GSS_C_AF_INET;
		    bindings.acceptor_address.length = 4;
		    bindings.acceptor_address.value =
			 &rqst->rq_xprt->xp_laddr.sin_addr.s_addr;
	       } else {
		    LOG_MISCERR("cannot get local address");
		    ret = AUTH_FAILED;
		    goto error;
	       }


	       bindp = &bindings;
	  } else {
	       bindp = GSS_C_NO_CHANNEL_BINDINGS;
	  }

	  /*
	   * If the client's server_creds is already set, use it.
	   * Otherwise, try each credential in server_creds_list until
	   * one of them succeedes, then set the client server_creds
	   * to that.  If all fail, the client's server_creds isn't
	   * set (which is fine, because the client will be gc'ed
	   * anyway).
	   *
	   * If accept_sec_context returns something other than
	   * success and GSS_S_FAILURE, then assume different
	   * credentials won't help and stop looping.
	   * 
	   * Note that there are really two cases here: (1) the client
	   * has a server_creds already, and (2) it does not.  They
	   * are both written in the same loop so that there is only
	   * one textual call to gss_accept_sec_context; in fact, in
	   * case (1), the loop is executed exactly once.
	   */
	  for (i = 0; i < server_creds_count; i++) {
	       if (client_data->server_creds != NULL) {
		    PRINTF(("svcauth_gssapi: using's clients server_creds\n"));
		    server_creds = client_data->server_creds;
	       } else {
		    PRINTF(("svcauth_gssapi: trying creds %d\n", i));
		    server_creds = server_creds_list[i];
	       }
	       
	       /* Free previous output_token from loop */
	       if(i != 0) gss_release_buffer(&minor_stat, &output_token);

	       call_res.gss_major =
		    gss_accept_sec_context(&call_res.gss_minor,
					   &client_data->context,
					   server_creds,
					   &call_arg.token,
					   bindp,
					   &client_data->client_name,
					   NULL,
					   &output_token,
					   &ret_flags,
					   &time_rec,
					   NULL);

	       if (server_creds == client_data->server_creds)
		    break;

	       PRINTF(("accept_sec_context returned 0x%x 0x%x wrong-princ=%#x\n",
		       call_res.gss_major, call_res.gss_minor, (int) KRB5KRB_AP_WRONG_PRINC));
	       if (call_res.gss_major == GSS_S_COMPLETE ||
		   call_res.gss_major == GSS_S_CONTINUE_NEEDED) {
		    /* server_creds was right, set it! */
		    PRINTF(("svcauth_gssapi: creds are correct, storing\n"));
		    client_data->server_creds = server_creds;
		    client_data->server_name = server_name_list[i];
		    break;
	       } else if (call_res.gss_major != GSS_S_FAILURE
#ifdef GSSAPI_KRB5
			  /*
			   * hard-coded because there is no other way
			   * to prevent all GSS_S_FAILURES from
			   * returning a "wrong principal in request"
			   * error
			   */
			  || ((krb5_error_code) call_res.gss_minor !=
			      (krb5_error_code) KRB5KRB_AP_WRONG_PRINC)
#endif
			  ) {
		    break;
	       }
	  }
	  
	  gssstat = call_res.gss_major;
	  minor_stat = call_res.gss_minor;

	  /* done with call args */
	  xdr_free(xdr_authgssapi_init_arg, &call_arg);

	  PRINTF(("svcauth_gssapi: accept_sec_context returned %#x %#x\n",
		  call_res.gss_major, call_res.gss_minor));
	  if (call_res.gss_major != GSS_S_COMPLETE &&
	      call_res.gss_major != GSS_S_CONTINUE_NEEDED) {
	       AUTH_GSSAPI_DISPLAY_STATUS(("accepting context",
					   call_res.gss_major,
					   call_res.gss_minor));

	       if (log_badauth != NULL)
		    (*log_badauth)(call_res.gss_major,
				   call_res.gss_minor,
				   &rqst->rq_xprt->xp_raddr,
				   log_badauth_data);
	       
	       gss_release_buffer(&minor_stat, &output_token);
	       svc_sendreply(rqst->rq_xprt, xdr_authgssapi_init_res,
			     (caddr_t) &call_res);
	       *no_dispatch = TRUE;
	       ret = AUTH_OK;
	       goto error;
	  }
	      
	  if (output_token.length != 0) {
	       PRINTF(("svcauth_gssapi: got new output token\n"));
	       GSS_COPY_BUFFER(call_res.token, output_token);
	  }

	  if (gssstat == GSS_S_COMPLETE) {
	       client_data->seq_num = rand();
	       client_expire(client_data,
			     (time_rec == GSS_C_INDEFINITE ?
			      INDEF_EXPIRE : time_rec) + time(0));

	       PRINTF(("svcauth_gssapi: context established, isn %d\n", 
		       client_data->seq_num));

	       if (auth_gssapi_seal_seq(client_data->context,
					client_data->seq_num,
					&call_res.signed_isn) ==
		   FALSE) {
		    ret = AUTH_FAILED;
		    LOG_MISCERR("internal error sealing sequence number");
		    gss_release_buffer(&minor_stat, &output_token);
		    goto error;
	       }
	  }

	  PRINTF(("svcauth_gssapi: sending reply\n"));
	  svc_sendreply(rqst->rq_xprt, xdr_authgssapi_init_res,
			(caddr_t) &call_res);
	  *no_dispatch = TRUE;

	  /*
	   * If appropriate, set established to TRUE *after* sending
	   * response (otherwise, the client will receive the final
	   * token encrypted)
	   */
	  if (gssstat == GSS_S_COMPLETE) {
	       gss_release_buffer(&minor_stat, &call_res.signed_isn);
	       client_data->established = TRUE;
	  }
	  gss_release_buffer(&minor_stat, &output_token);
     } else {
	  PRINTF(("svcauth_gssapi: context is established\n"));

	  /* check the verifier */
	  PRINTF(("svcauth_gssapi: checking verifier, len %d\n",
		  verf->oa_length));
	  
	  in_buf.length = verf->oa_length;
	  in_buf.value = verf->oa_base;
	  
	  if (auth_gssapi_unseal_seq(client_data->context, &in_buf,
				     &seq_num) == FALSE) {
	       ret = AUTH_BADVERF;
	       LOG_MISCERR("internal error unsealing sequence number");
	       goto error;
	  }
	  
	  if (seq_num != client_data->seq_num + 1) {
	       PRINTF(("svcauth_gssapi: expected isn %d, got %d\n",
		       client_data->seq_num + 1, seq_num));
	       if (log_badverf != NULL)
		    (*log_badverf)(client_data->client_name,
				   client_data->server_name,
				   rqst, msg, log_badverf_data);
	       
	       ret = AUTH_REJECTEDVERF;
	       goto error;
	  }
	  client_data->seq_num++;
	  
	  PRINTF(("svcauth_gssapi: seq_num %d okay\n", seq_num));

	  /* free previous response verifier, if any */
	  if (client_data->prev_verf.length != 0) {
	       gss_release_buffer(&minor_stat, &client_data->prev_verf);
	       client_data->prev_verf.length = 0;
	  }
	  
	  /* prepare response verifier */
	  seq_num = client_data->seq_num + 1;
	  if (auth_gssapi_seal_seq(client_data->context, seq_num,
				   &out_buf) == FALSE) {
	       ret = AUTH_FAILED;
	       LOG_MISCERR("internal error sealing sequence number");
	       goto error;
	  }
	  
	  client_data->seq_num++;
	  
	  PRINTF(("svcauth_gssapi; response seq_num %d\n", seq_num));
	  
	  rqst->rq_xprt->xp_verf.oa_flavor = AUTH_GSSAPI;
	  rqst->rq_xprt->xp_verf.oa_base = out_buf.value; 
	  rqst->rq_xprt->xp_verf.oa_length = out_buf.length;

	  /* save verifier so it can be freed next time */
	  client_data->prev_verf.value = out_buf.value; 
	  client_data->prev_verf.length = out_buf.length;

	  /*
	   * Message is authentic.  If auth_msg if true, process the
	   * call; otherwise, return AUTH_OK so it will be dispatched
	   * to the application server.
	   */

	  if (creds.auth_msg == TRUE) {
	       /*
		* If process_token fails, then the token probably came
		* from an attacker.  No response (error or otherwise)
		* should be returned to the client, since it won't be
		* accepting one.
		*/

	       switch (rqst->rq_proc) {
	       case AUTH_GSSAPI_MSG:
		    PRINTF(("svcauth_gssapi: GSSAPI_MSG, getting args\n"));
		    memset(&call_arg, 0, sizeof(call_arg));
		    if (! svc_getargs(rqst->rq_xprt, xdr_authgssapi_init_arg,
				      &call_arg)) {
			 PRINTF(("svcauth_gssapi: cannot decode args\n"));
			 LOG_MISCERR("protocol error in call arguments");
			 xdr_free(xdr_authgssapi_init_arg, &call_arg);
			 ret = AUTH_BADCRED;
			 goto error;
		    }

		    PRINTF(("svcauth_gssapi: processing token\n"));
		    gssstat = gss_process_context_token(&minor_stat,
							client_data->context,
							&call_arg.token);

		    /* done with call args */
		    xdr_free(xdr_authgssapi_init_arg, &call_arg);
		    
		    if (gssstat != GSS_S_COMPLETE) {
			 AUTH_GSSAPI_DISPLAY_STATUS(("processing token",
						     gssstat, minor_stat));
			 ret = AUTH_FAILED;
			 goto error;
		    }

		    svc_sendreply(rqst->rq_xprt, xdr_void, NULL);
		    *no_dispatch = TRUE;
		    break;

	       case AUTH_GSSAPI_DESTROY:
		    PRINTF(("svcauth_gssapi: GSSAPI_DESTROY\n"));
		    
		    PRINTF(("svcauth_gssapi: sending reply\n"));
		    svc_sendreply(rqst->rq_xprt, xdr_void, NULL);
		    *no_dispatch = TRUE;

		    destroy_client(client_data);
		    rqst->rq_xprt->xp_auth = NULL;
		    break;

	       default:
		    PRINTF(("svcauth_gssapi: unacceptable procedure %d\n",
			    rqst->rq_proc));
		    LOG_MISCERR("invalid call procedure number");
		    ret = AUTH_FAILED;
		    goto error;
	       }
	  } else {
	       /* set credentials for app server; comment in svc.c */
	       /* seems to imply this is incorrect, but I don't see */
	       /* any problem with it... */
	       rqst->rq_clntcred = (char *)client_data->client_name;
	       rqst->rq_svccred = (char *)client_data->context;
	  }
     }

     if (creds.client_handle.length != 0) {
	  PRINTF(("svcauth_gssapi: freeing client_handle len %d\n",
		  (int) creds.client_handle.length));
	  xdr_free(xdr_authgssapi_creds, &creds);
     }
     
     PRINTF(("\n"));
     return AUTH_OK;

error:
     if (creds.client_handle.length != 0) {
	  PRINTF(("svcauth_gssapi: freeing client_handle len %d\n",
		  (int) creds.client_handle.length));
	  xdr_free(xdr_authgssapi_creds, &creds);
     }
     
     PRINTF(("\n"));
     return ret;
}
コード例 #27
0
ファイル: ldm_server.c プロジェクト: khallock/LDM
hiya_reply_t*
hiya_6_svc(
        prod_class_t *offered,
        struct svc_req *rqstp)
{
    const char* const pqfname = getQueuePath();
    static hiya_reply_t reply;
    SVCXPRT * const xprt = rqstp->rq_xprt;
    struct sockaddr_in *upAddr = (struct sockaddr_in*) svc_getcaller(xprt);
    const char *upName = hostbyaddr(upAddr);
    int error;
    int isPrimary;
    unsigned int maxHereis;
    static prod_class_t *accept;

    /*
     * Open the product-queue for writing.  It will be closed by cleanup()
     * during process termination.
     */
    if (pq) {
        (void) pq_close(pq);
        pq = NULL;
    }
    error = pq_open(pqfname, PQ_DEFAULT, &pq);
    if (error) {
        err_log_and_free(ERR_NEW2(error, NULL,
                "Couldn't open product-queue \"%s\" for writing: %s",
                pqfname,
                PQ_CORRUPT == error
                ? "The product-queue is inconsistent"
                : strerror(error)), ERR_FAILURE);
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }

    /* else */

    error = down6_init(upName, upAddr, pqfname, pq);
    if (error) {
        uerror("Couldn't initialize downstream LDM");
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }
    else {
        uinfo("Downstream LDM initialized");
    }

    /*
     * The previous "accept" is freed here -- rather than freeing the
     * soon-to-be-allocated "accept" at the end of its block -- because it can
     * be used in the reply.
     */
    if (accept) {
        free_prod_class(accept); /* NULL safe */
        accept = NULL;
    }

    error = lcf_reduceToAcceptable(upName, inet_ntoa(upAddr->sin_addr), offered,
            &accept, &isPrimary);

    maxHereis = isPrimary ? UINT_MAX : 0;

    if (error) {
        serror("Couldn't validate HIYA");
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }
    else {
        if (ulogIsDebug())
            udebug("intersection: %s", s_prod_class(NULL, 0, accept));

        if (accept->psa.psa_len == 0) {
            uwarn("Empty intersection of HIYA offer from %s (%s) and ACCEPT "
                    "entries", upName, s_prod_class(NULL, 0, offered));
            svcerr_weakauth(xprt);
            svc_destroy(xprt);
            exit(0);
        }
        else {
            error = down6_set_prod_class(accept);

            if (error) {
                if (DOWN6_SYSTEM_ERROR == error) {
                    serror("Couldn't set product class: %s",
                            s_prod_class(NULL, 0, accept));
                }
                else {
                    uerror("Couldn't set product class: %s",
                            s_prod_class(NULL, 0, accept));
                }

                svcerr_systemerr(xprt);
                svc_destroy(xprt);
                exit(EXIT_FAILURE);
            }

            /* else */

            if (clss_eq(offered, accept)) {
                unotice("hiya6: %s", s_prod_class(NULL, 0, offered));

                reply.code = OK;
                reply.hiya_reply_t_u.max_hereis = maxHereis;
            }
            else {
                if (ulogIsVerbose()) {
                    char off[512];
                    char acc[512];

                    (void) s_prod_class(off, sizeof(off), offered), (void) s_prod_class(
                            acc, sizeof(acc), accept);

                    uinfo("hiya6: RECLASS: %s -> %s", off, acc);
                }

                reply.code = RECLASS;
                reply.hiya_reply_t_u.feedPar.prod_class = accept;
                reply.hiya_reply_t_u.feedPar.max_hereis = maxHereis;
            }
        } /* product-intersection != empty set */
    } /* successful acl_check_hiya() */

    return &reply;
}
コード例 #28
0
ファイル: ldm_server.c プロジェクト: khallock/LDM
/**
 * Feeds or notifies a downstream LDM. This function returns either NULL or a
 * reply to be sent to the downstream LDM (e.g., a RECLASS message) or
 * terminates this process (hopefully after sending some data).
 * 
 * @param xprt          [in/out] Pointer to server-side transport handle.
 * @param want          [in] Pointer to subscription by downstream LDM.
 *                      May contain a "signature" product-specification.
 * @param isNotifier    [in] Whether or not the upstream LDM is a feeder or a
 *                      notifier.
 * @param maxHereis     Maximum HEREIS size parameter. Ignored if "isNotifier"
 *                      is true.
 * @return              The reply for the downstream LDM or NULL if no reply
 *                      should be made.
 */
static fornme_reply_t*
feed_or_notify(
    SVCXPRT* const              xprt,
    const prod_class_t* const   want,
    const int                   isNotifier,
    const max_hereis_t          maxHereis)
{
    struct sockaddr_in      downAddr = *svc_getcaller(xprt);
    ErrorObj*               errObj;
    int                     status;
    char*                   downName = NULL;
    prod_class_t*           origSub = NULL;
    prod_class_t*           allowSub = NULL;
    const signaturet*       signature = NULL;
    UpFilter*               upFilter = NULL;
    fornme_reply_t*         reply = NULL;
    int                     isPrimary;
    static fornme_reply_t   theReply;
    static prod_class_t*    uldbSub = NULL;

    /*
     * Clean-up from a (possibly) previous invocation
     */
    (void)memset(&theReply, 0, sizeof(theReply));
    if (uldbSub != NULL) {
        free_prod_class(uldbSub);
        uldbSub = NULL;
    }

    downName = strdup(hostbyaddr(&downAddr));
    if (NULL == downName) {
        LOG_ADD1("Couldn't duplicate downstream host name: \"%s\"",
                hostbyaddr(&downAddr));
        log_log(LOG_ERR);
        svcerr_systemerr(xprt);
        goto return_or_exit;
    }

    set_abbr_ident(downName, isNotifier ? "(noti)" : "(feed)");

    /*
     * Remove any "signature" specification from the subscription.
     */
    if ((errObj = separateProductClass(want, &origSub, &signature)) != NULL) {
        err_log_and_free(errObj, ERR_FAILURE);
        svcerr_systemerr(xprt);
        goto free_down_name;
    }

    /*
     * Get the upstream filter
     */
    errObj = lcf_getUpstreamFilter(downName, &downAddr.sin_addr, origSub,
            &upFilter);
    if (errObj) {
        err_log_and_free(ERR_NEW(0, errObj,
                "Couldn't get \"upstream\" filter"), ERR_FAILURE);
        svcerr_systemerr(xprt);
        goto free_orig_sub;
    }
    if (NULL == upFilter) {
        err_log_and_free(ERR_NEW1(0, NULL,
                "Upstream filter prevents data-transfer: %s",
                s_prod_class(NULL, 0, origSub)), ERR_FAILURE);
        svcerr_weakauth(xprt);
        goto free_orig_sub;
    }

    /* TODO: adjust time? */

    /*
     * Reduce the subscription according to what the downstream host is allowed
     * to receive.
     */
    status = lcf_reduceToAllowed(downName, &downAddr.sin_addr, origSub,
            &allowSub);
    if (status == ENOMEM) {
        LOG_SERROR0("Couldn't compute wanted/allowed product intersection");
        log_log(LOG_ERR);
        svcerr_systemerr(xprt);
        goto free_up_filter;
    }
    if (status == EINVAL) {
        LOG_ADD1("Invalid pattern in product-class: %s",
                s_prod_class(NULL, 0, origSub));
        log_log(LOG_WARNING);
        theReply.code = BADPATTERN;
        reply = &theReply;
        goto free_up_filter;
    }
    assert(status == 0);
    (void) logIfReduced(origSub, allowSub, "ALLOW entries");

    /*
     * Reduce the subscription according to existing subscriptions from the
     * same downstream host and, if `isAntiDosEnabled()` returns `true`,
     * terminate every previously-existing upstream LDM process that's feeding
     * (not notifying) a subset of the subscription to the same IP address.
     *
     * The following relies on atexit()-registered cleanup for removal of the
     * entry from the upstream LDM database.
     */
    isPrimary = maxHereis > UINT_MAX / 2;
    status = uldb_addProcess(getpid(), 6, &downAddr, allowSub, &uldbSub,
            isNotifier, isPrimary);
    if (status) {
        LOG_ADD0("Couldn't add this process to the upstream LDM database");
        log_log(LOG_ERR);
        svcerr_systemerr(xprt);
        goto free_allow_sub;
    }
    (void) logIfReduced(allowSub, uldbSub, "existing subscriptions");

    /*
     * Send a RECLASS reply to the downstream LDM if appropriate.
     */
    if (!clss_eq(origSub, uldbSub)) {
        theReply.code = RECLASS;

        if (0 < uldbSub->psa.psa_len) {
            /*
             * The downstream LDM is allowed less than it requested and was
             * entered into the upstream LDM database.
             */
            (void)uldb_remove(getpid()); /* maybe next time */

            theReply.fornme_reply_t_u.prod_class = uldbSub;
        }
        else {
            /*
             * The downstream LDM isn't allowed anything and wasn't entered
             * into the upstream LDM database.
             */
            static prod_class noSub = { { 0, 0 }, /* TS_ZERO */
                { 0, 0 }, /* TS_ZERO */ { 0, (prod_spec *) NULL } };

            theReply.fornme_reply_t_u.prod_class = &noSub;
        }

        reply = &theReply;

        goto free_allow_sub;
    }

    /*
     * Reply to the downstream LDM that the subscription will be honored.
     */
    theReply.code = OK;
    theReply.fornme_reply_t_u.id = (unsigned) getpid();
    if (!svc_sendreply(xprt, (xdrproc_t)xdr_fornme_reply_t,
            (caddr_t)&theReply)) {
        LOG_ADD0("svc_sendreply(...) failure");
        log_log(LOG_ERR);
        svcerr_systemerr(xprt);
        goto free_allow_sub;
    }

    /*
     * Wait a second before sending anything to the downstream LDM.
     */
    (void) sleep(1);

    status = isNotifier
            ? up6_new_notifier(xprt->xp_sock, downName, &downAddr, uldbSub,
                    signature, getQueuePath(), interval, upFilter)
            : up6_new_feeder(xprt->xp_sock, downName, &downAddr, uldbSub,
                    signature, getQueuePath(), interval, upFilter,
                    isPrimary);

    svc_destroy(xprt); /* closes the socket */
    exit(status);

    /*
     * Reply and error handling:
     */
    free_allow_sub:
        free_prod_class(allowSub);

    free_up_filter:
        upFilter_free(upFilter);

    free_orig_sub:
        free_prod_class(origSub);

    free_down_name:
        free(downName);

    return_or_exit:
        return reply;
}
コード例 #29
0
ファイル: mount3udp_svc.c プロジェクト: AsherBond/glusterfs
static void
mountudp_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
{
        union {
                dirpath mountudpproc3_mnt_3_arg;
        } argument;
        char                    *result = NULL;
        xdrproc_t               _xdr_argument = NULL, _xdr_result = NULL;
        char *(*local)(char *, struct svc_req *) = NULL;
        mountres3               *res = NULL;
        struct sockaddr_in      *sin = NULL;

        sin = svc_getcaller (transp);
        inet_ntop (AF_INET, &sin->sin_addr, mnthost, INET_ADDRSTRLEN+1);

        switch (rqstp->rq_proc) {
        case NULLPROC:
                (void) svc_sendreply (transp, (xdrproc_t) xdr_void,
                                      (char *)NULL);
                return;

        case MOUNT3_MNT:
                _xdr_argument = (xdrproc_t) xdr_dirpath;
                _xdr_result = (xdrproc_t) xdr_mountres3;
                local = (char *(*)(char *,
                                   struct svc_req *)) mountudpproc3_mnt_3_svc;
                break;

        case MOUNT3_UMNT:
                _xdr_argument = (xdrproc_t) xdr_dirpath;
                _xdr_result = (xdrproc_t) xdr_mountstat3;
                local = (char *(*)(char *,
                                   struct svc_req *)) mountudpproc3_umnt_3_svc;
                break;

        default:
                svcerr_noproc (transp);
                return;
        }
        memset ((char *)&argument, 0, sizeof (argument));
        if (!svc_getargs (transp, (xdrproc_t) _xdr_argument,
                          (caddr_t) &argument)) {
                svcerr_decode (transp);
                return;
        }
        result = (*local)((char *)&argument, rqstp);
        if (result == NULL) {
                gf_log (GF_MNT, GF_LOG_DEBUG, "PROC returned error");
                svcerr_systemerr (transp);
        }
        if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result,
                                             result)) {
                gf_log (GF_MNT, GF_LOG_ERROR, "svc_sendreply returned error");
                svcerr_systemerr (transp);
        }
        if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument,
                           (caddr_t) &argument)) {
                gf_log (GF_MNT, GF_LOG_ERROR, "unable to free arguments");
        }
        if (result == NULL)
                return;
        /* free the result */
        switch (rqstp->rq_proc) {
        case MOUNT3_MNT:
                res = (mountres3 *) result;
                GF_FREE (res->mountres3_u.mountinfo.fhandle.fhandle3_val);
                GF_FREE (res->mountres3_u.mountinfo.auth_flavors.auth_flavors_val);
                GF_FREE (res);
                break;

        case MOUNT3_UMNT:
                GF_FREE (result);
                break;
        }
        return;
}
コード例 #30
0
/*
 * find the address of the caller of an RPC procedure.
 */
struct sockaddr_in *
amu_svc_getcaller(SVCXPRT *xprt)
{
  /* glibc 2.2 returns a sockaddr_storage ??? */
  return (struct sockaddr_in *) svc_getcaller(xprt);
}