Пример #1
0
int sysapi_queue_deque_all(void (*cbfunc)(void *elem, void *magic),
                               void *magic,
                               void *qptr)
{
    struct sysapi_queue_head *qhead = qptr;
    struct sysapi_queue *elem;

    elem = qhead->head;

    for (; elem;) {
        cbfunc(elem->data, magic);
        qhead->head = elem->next;
        free(elem);
        elem = qhead->head;
    }
}
Пример #2
0
int sysapi_queue_deque(void (*cbfunc)(void *elem, void *magic),
                         void *magic,
                         void *qptr)
{
    struct sysapi_queue_head *qhead = qptr;
    struct sysapi_queue *elem;
    
    elem = qhead->head;
    if (!elem)
        return -1;
    
    cbfunc(elem->data, magic);
    qhead->head = elem->next;
    free(elem);
    
    return 0;
}
static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name,
						    const char *service,
						    struct addrinfo *in,
						    int (*cbfunc)(void *, int, struct sockaddr *),
						    void *cbdata)
{
	struct addrinfo *out = NULL;
	int ret;
	int count = 3;

	while (count) {

		ret = getaddrinfo(name, service, in, &out);
		if (ret == 0) {
			break;
		}

		if (ret == EAI_AGAIN) {
			count--;
			continue;
		}

#ifdef DEBUG_KRB5
		fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
			"getaddrinfo failed: %s (%d)\n",
			(unsigned int)getpid(), gai_strerror(ret), ret);
#endif

		return KRB5_PLUGIN_NO_HANDLE;
	}

	ret = cbfunc(cbdata, out->ai_socktype, out->ai_addr);
#ifdef DEBUG_KRB5
	if (ret) {
		fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
			"failed to call callback: %s (%d)\n",
			(unsigned int)getpid(), error_message(ret), ret);
	}
#endif

	freeaddrinfo(out);
	return ret;
}
Пример #4
0
krb5_error_code
_krb5_override_service_locator(
    void *arg0,
    enum locate_service_type svc,
    const char *realm,
    int socktype,
    int family,
    int (*cbfunc)(void *, int, struct sockaddr *),
    void *cbdata)
{
	_NOTE(ARGUNUSED(arg0))
	smb_domainex_t dxi;
	int rc = KRB5_PLUGIN_NO_HANDLE;
	short port;

	/*
	 * Is this a service we want to override?
	 */
	switch (svc) {
	case locate_service_kdc:
	case locate_service_master_kdc:
		port = htons(KRB5_DEFAULT_PORT);
		break;
	case locate_service_kadmin:
		port = htons(DEFAULT_KADM5_PORT);
		break;
	case locate_service_kpasswd:
		port = htons(DEFAULT_KPASSWD_PORT);
		break;
	case locate_service_krb524:
	default:
		return (rc);
	}

	/*
	 * What's my domain?  Note: have to get this in a way
	 * that works while join domain is underway.
	 */
	if (!smb_domain_getinfo(&dxi)) {
		smbd_report("_krb5_override_service_locator "
		    "failed getting domain info");
		return (KRB5_ERR_HOST_REALM_UNKNOWN);
	}

	/*
	 * Is this a realm we want to override?
	 */
	if (0 != strcasecmp(realm, dxi.d_primary.di_fqname)) {
		syslog(LOG_DEBUG, "_krb5_override_service_locator, "
		    "realm=%s, fqdn=%s", realm, dxi.d_primary.di_fqname);
		return (rc);
	}

	/*
	 * Yes, this is our domain.  Have a DC?
	 */
	if (dxi.d_dci.dc_name[0] == '\0' ||
	    dxi.d_dci.dc_addr.a_family == 0)
		return (KRB5_REALM_CANT_RESOLVE);

	switch (family) {
	case AF_UNSPEC:
		break;	/* OK */
	case AF_INET:
	case AF_INET6:
		if (family == dxi.d_dci.dc_addr.a_family)
			break;	/* OK */
		/* else fallthrough */
	default:
		return (KRB5_ERR_NO_SERVICE);
	}

	/*
	 * Provide the service address we have.
	 */
	switch (dxi.d_dci.dc_addr.a_family) {
	case AF_INET: {
		struct sockaddr_in sin;
		(void) memset(&sin, 0, sizeof (sin));
		sin.sin_family = AF_INET;
		sin.sin_port = port;
		(void) memcpy(&sin.sin_addr, &dxi.d_dci.dc_addr.a_ipv4,
		    sizeof (sin.sin_addr));
		rc = cbfunc(cbdata, socktype, (struct sockaddr *)&sin);
		/* rc from cbfunc is special. */
		if (rc)
			rc = ENOMEM;
		break;
	}
	case AF_INET6: {
		struct sockaddr_in6 sin6;
		(void) memset(&sin6, 0, sizeof (sin6));
		sin6.sin6_family = AF_INET6;
		sin6.sin6_port = port;
		(void) memcpy(&sin6.sin6_addr, &dxi.d_dci.dc_addr.a_ipv6,
		    sizeof (sin6.sin6_addr));
		rc = cbfunc(cbdata, socktype, (struct sockaddr *)&sin6);
		/* rc from cbfunc is special. */
		if (rc)
			rc = ENOMEM;
		break;
	}
	default:
		rc = KRB5_ERR_NO_SERVICE;
		break;
	}

	return (rc);
}
Пример #5
0
static krb5_error_code
lookup(void *blob, enum locate_service_type svc, const char *realm,
       int socktype, int family,
       int (*cbfunc)(void *, int, struct sockaddr *), void *cbdata)
{
    PyObject *py_result, *svcarg, *realmarg, *arglist;
    int listsize, i, x;
    struct addrinfo aihints, *airesult;
    int thissocktype;

//    fprintf(stderr, "%s:%d: lookup(%d,%s,%d,%d)\n", F, __LINE__,
//          svc, realm, socktype, family);
    sctx = blob;                /* XXX: Not thread safe!  */
    i = CALL_INIT_FUNCTION (my_init);
    if (i) {
#if 0
        fprintf(stderr, "%s:%d: module initialization failed\n", F, __LINE__);
#endif
        return i;
    }
    if (locatefn == 0)
        return KRB5_PLUGIN_NO_HANDLE;
    svcarg = PyInt_FromLong (svc);
    /* error? */
    realmarg = PyString_FromString ((char *) realm);
    /* error? */
    arglist = PyTuple_New (4);
    /* error? */

    PyTuple_SetItem (arglist, 0, svcarg);
    PyTuple_SetItem (arglist, 1, realmarg);
    PyTuple_SetItem (arglist, 2, PyInt_FromLong (socktype));
    PyTuple_SetItem (arglist, 3, PyInt_FromLong (family));
    /* references handed off, no decref */

    py_result = PyObject_CallObject (locatefn, arglist);
    Py_DECREF (arglist);
    if (PyErr_Occurred()) {
        fprintf(stderr,"%s:%d: python error\n", F, __LINE__);
        PyErr_Print();
        krb5_set_error_message(blob, -1,
                               "Python evaluation error, see stderr");
        return -1;
    }
    if (py_result == 0) {
        fprintf(stderr, "%s:%d: returned null object\n", F, __LINE__);
        return -1;
    }
    if (py_result == Py_False)
        return KRB5_PLUGIN_NO_HANDLE;
    if (! PyList_Check (py_result)) {
        Py_DECREF (py_result);
        fprintf(stderr, "%s:%d: returned non-list, non-False\n", F, __LINE__);
        krb5_set_error_message(blob, -1,
                               "Python script error -- returned non-list, non-False result");
        return -1;
    }
    listsize = PyList_Size (py_result);
    /* allocate */
    memset(&aihints, 0, sizeof(aihints));
    aihints.ai_flags = AI_NUMERICHOST;
    aihints.ai_family = family;
    for (i = 0; i < listsize; i++) {
        PyObject *answer, *field;
        char *hoststr, *portstr, portbuf[3*sizeof(long) + 4];
        int cbret;

        answer = PyList_GetItem (py_result, i);
        if (! PyTuple_Check (answer)) {
            krb5_set_error_message(blob, -1,
                                   "Python script error -- returned item %d not a tuple", i);
            /* leak?  */
            return -1;
        }
        if (PyTuple_Size (answer) != 3) {
            krb5_set_error_message(blob, -1,
                                   "Python script error -- returned tuple %d size %d should be 3",
                                   i, PyTuple_Size (answer));
            /* leak?  */
            return -1;
        }
        field = PyTuple_GetItem (answer, 0);
        if (! PyString_Check (field)) {
            /* leak?  */
            krb5_set_error_message(blob, -1,
                                   "Python script error -- first component of tuple %d is not a string",
                                   i);
            return -1;
        }
        hoststr = PyString_AsString (field);
        field = PyTuple_GetItem (answer, 1);
        if (PyString_Check (field)) {
            portstr = PyString_AsString (field);
        } else if (PyInt_Check (field)) {
            snprintf(portbuf, sizeof(portbuf), "%ld", PyInt_AsLong (field));
            portstr = portbuf;
        } else {
            krb5_set_error_message(blob, -1,
                                   "Python script error -- second component of tuple %d neither a string nor an integer",
                                   i);
            /* leak?  */
            return -1;
        }
        field = PyTuple_GetItem (answer, 2);
        if (! PyInt_Check (field)) {
            krb5_set_error_message(blob, -1,
                                   "Python script error -- third component of tuple %d not an integer",
                                   i);
            /* leak?  */
            return -1;
        }
        thissocktype = PyInt_AsLong (field);
        switch (thissocktype) {
        case SOCK_STREAM:
        case SOCK_DGRAM:
            /* okay */
            if (socktype != 0 && socktype != thissocktype) {
                krb5_set_error_message(blob, -1,
                                       "Python script error -- tuple %d has socket type %d, should only have %d",
                                       i, thissocktype, socktype);
                /* leak?  */
                return -1;
            }
            break;
        default:
            /* 0 is not acceptable */
            krb5_set_error_message(blob, -1,
                                   "Python script error -- tuple %d has invalid socket type %d",
                                   i, thissocktype);
            /* leak?  */
            return -1;
        }
        aihints.ai_socktype = thissocktype;
        aihints.ai_flags = AI_ADDRCONFIG;
        x = getaddrinfo (hoststr, portstr, &aihints, &airesult);
        if (x != 0)
            continue;
        cbret = cbfunc(cbdata, airesult->ai_socktype, airesult->ai_addr);
        freeaddrinfo(airesult);
        if (cbret != 0)
            break;
    }
    Py_DECREF (py_result);
    return 0;
}