Example #1
0
/*
 *	Find which interface to use.
 */
int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
{
	ax25_route *ax25_rt;
	ax25_address *call;

	if ((ax25_rt = ax25_find_route(addr, NULL)) == NULL)
		return -EHOSTUNREACH;

	if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL)
		return -EHOSTUNREACH;

	if ((call = ax25_findbyuid(current->euid)) == NULL) {
		if (ax25_uid_policy && !suser())
			return -EPERM;
		call = (ax25_address *)ax25->ax25_dev->dev->dev_addr;
	}

	ax25->source_addr = *call;

	if (ax25_rt->digipeat != NULL) {
		if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL)
			return -ENOMEM;
		*ax25->digipeat = *ax25_rt->digipeat;
		ax25_adjust_path(addr, ax25->digipeat);
	}

	if (ax25->sk != NULL)
		ax25->sk->zapped = 0;

	return 0;
}
Example #2
0
/*
 *	Find which interface to use.
 */
int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
{
	ax25_uid_assoc *user;
	ax25_route *ax25_rt;
	int err = 0;

	ax25_route_lock_use();
	ax25_rt = ax25_get_route(addr, NULL);
	if (!ax25_rt) {
		ax25_route_lock_unuse();
		return -EHOSTUNREACH;
	}
	if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
		err = -EHOSTUNREACH;
		goto put;
	}

	user = ax25_findbyuid(current_euid());
	if (user) {
		ax25->source_addr = user->call;
		ax25_uid_put(user);
	} else {
		if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
			err = -EPERM;
			goto put;
		}
		ax25->source_addr = *(ax25_address *)ax25->ax25_dev->dev->dev_addr;
	}

	if (ax25_rt->digipeat != NULL) {
		ax25->digipeat = kmemdup(ax25_rt->digipeat, sizeof(ax25_digi),
					 GFP_ATOMIC);
		if (ax25->digipeat == NULL) {
			err = -ENOMEM;
			goto put;
		}
		ax25_adjust_path(addr, ax25->digipeat);
	}

	if (ax25->sk != NULL) {
		bh_lock_sock(ax25->sk);
		sock_reset_flag(ax25->sk, SOCK_ZAPPED);
		bh_unlock_sock(ax25->sk);
	}

put:
	ax25_route_lock_unuse();
	return err;
}
Example #3
0
/*
 *	Find which interface to use.
 */
int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
{
	ax25_route *ax25_rt;
	ax25_address *call;
	int err;

	if ((ax25_rt = ax25_get_route(addr, NULL)) == NULL)
		return -EHOSTUNREACH;

	if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
		err = -EHOSTUNREACH;
		goto put;
	}

	if ((call = ax25_findbyuid(current->euid)) == NULL) {
		if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
			err = -EPERM;
			goto put;
		}
		call = (ax25_address *)ax25->ax25_dev->dev->dev_addr;
	}

	ax25->source_addr = *call;

	if (ax25_rt->digipeat != NULL) {
		if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
			err = -ENOMEM;
			goto put;
		}
		memcpy(ax25->digipeat, ax25_rt->digipeat, sizeof(ax25_digi));
		ax25_adjust_path(addr, ax25->digipeat);
	}

	if (ax25->sk != NULL) {
		bh_lock_sock(ax25->sk);
		ax25->sk->sk_zapped = 0;
		bh_unlock_sock(ax25->sk);
	}

put:
	ax25_put_route(ax25_rt);

	return 0;
}
Example #4
0
int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
{
	ax25_uid_assoc *s, *ax25_uid;
	unsigned long flags;

	switch (cmd) {
		case SIOCAX25GETUID:
			for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) {
				if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0)
					return ax25_uid->uid;
			}
			return -ENOENT;

		case SIOCAX25ADDUID:
			if (!capable(CAP_NET_ADMIN))
				return -EPERM;
			if (ax25_findbyuid(sax->sax25_uid))
				return -EEXIST;
			if (sax->sax25_uid == 0)
				return -EINVAL;
			if ((ax25_uid = kmalloc(sizeof(*ax25_uid), GFP_KERNEL)) == NULL)
				return -ENOMEM;
			ax25_uid->uid  = sax->sax25_uid;
			ax25_uid->call = sax->sax25_call;
			save_flags(flags); cli();
			ax25_uid->next = ax25_uid_list;
			ax25_uid_list  = ax25_uid;
			restore_flags(flags);
			return 0;

		case SIOCAX25DELUID:
			if (!capable(CAP_NET_ADMIN))
				return -EPERM;
			for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) {
				if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0)
					break;
			}
			if (ax25_uid == NULL)
				return -ENOENT;
			save_flags(flags); cli();
			if ((s = ax25_uid_list) == ax25_uid) {
				ax25_uid_list = s->next;
				restore_flags(flags);
				kfree(ax25_uid);
				return 0;
			}
			while (s != NULL && s->next != NULL) {
				if (s->next == ax25_uid) {
					s->next = ax25_uid->next;
					restore_flags(flags);
					kfree(ax25_uid);
					return 0;
				}
				s = s->next;
			}
			restore_flags(flags);
			return -ENOENT;

		default:
			return -EINVAL;
	}

	return -EINVAL;	/*NOTREACHED */
}