/*@-incondefs@*/ /* _et_list is global on unix but not in header annotations */ errcode_t KRB5_CALLCONV add_error_table(/*@dependent@*/ const struct error_table * et) /*@modifies _et_list,et_list_dynamic@*/ /*@=incondefs@*/ { struct dynamic_et_list *del; int merr; if (CALL_INIT_FUNCTION(com_err_initialize)) return 0; del = (struct dynamic_et_list *)malloc(sizeof(struct dynamic_et_list)); if (del == NULL) return ENOMEM; del->table = et; merr = k5_mutex_lock(&et_list_lock); if (merr) { free(del); return merr; } del->next = et_list_dynamic; et_list_dynamic = del; return k5_mutex_unlock(&et_list_lock); }
errcode_t KRB5_CALLCONV add_error_table(const struct error_table *et) { struct et_list *e; if (CALL_INIT_FUNCTION(com_err_initialize)) return 0; e = malloc(sizeof(struct et_list)); if (e == NULL) return ENOMEM; e->table = et; k5_mutex_lock(&et_list_lock); e->next = et_list; et_list = e; /* If there are two strings at the end of the table, they are a text domain * and locale dir, and we are supposed to call bindtextdomain. */ if (et->msgs[et->n_msgs] != NULL && et->msgs[et->n_msgs + 1] != NULL) bindtextdomain(et->msgs[et->n_msgs], et->msgs[et->n_msgs + 1]); k5_mutex_unlock(&et_list_lock); return 0; }
void *k5_getspecific (k5_key_t keynum) { struct tsd_block *t; int err; err = CALL_INIT_FUNCTION(krb5int_thread_support_init); if (err) return NULL; assert(keynum >= 0 && keynum < K5_KEY_MAX); assert(destructors_set[keynum] == 1); #ifndef ENABLE_THREADS t = &tsd_no_threads; #elif defined(_WIN32) t = TlsGetValue(tls_idx); #else /* POSIX */ if (K5_PTHREADS_LOADED) t = pthread_getspecific(key); else t = GET_NO_PTHREAD_TSD(); #endif if (t == NULL) return NULL; return t->values[keynum]; }
/*@-incondefs@*/ /* _et_list is global on unix but not in header annotations */ errcode_t KRB5_CALLCONV remove_error_table(const struct error_table * et) /*@modifies _et_list,et_list_dynamic@*/ /*@=incondefs@*/ { struct dynamic_et_list **del; struct et_list **el; int merr; if (CALL_INIT_FUNCTION(com_err_initialize)) return 0; merr = k5_mutex_lock(&et_list_lock); if (merr) return merr; /* Remove the entry that matches the error table instance. Prefer dynamic entries, but if there are none, check for a static one too. */ for (del = &et_list_dynamic; *del; del = &(*del)->next) if ((*del)->table == et) { /*@only@*/ struct dynamic_et_list *old = *del; *del = old->next; free (old); return k5_mutex_unlock(&et_list_lock); } for (el = &_et_list; *el; el = &(*el)->next) if ((*el)->table == et) { struct et_list *old = *el; *el = old->next; old->next = NULL; old->table = NULL; return k5_mutex_unlock(&et_list_lock); } k5_mutex_unlock(&et_list_lock); return ENOENT; }
static int kdb_lock_list() { int err; err = CALL_INIT_FUNCTION (kdb_init_lock_list); if (err) return err; return k5_mutex_lock(&db_lock); }
kim_error kim_os_library_unlock_for_bundle_lookup (void) { kim_error err = CALL_INIT_FUNCTION (kim_os_library_thread_init); if (!err) { err = k5_mutex_unlock (&g_bundle_lookup_mutex); } return err; }
int k5_key_register (k5_key_t keynum, void (*destructor)(void *)) { int err; err = CALL_INIT_FUNCTION(krb5int_thread_support_init); if (err) return err; assert(keynum >= 0 && keynum < K5_KEY_MAX); #ifndef ENABLE_THREADS assert(destructors_set[keynum] == 0); destructors[keynum] = destructor; destructors_set[keynum] = 1; err = 0; #elif defined(_WIN32) /* XXX: This can raise EXCEPTION_POSSIBLE_DEADLOCK. */ EnterCriticalSection(&key_lock); assert(destructors_set[keynum] == 0); destructors_set[keynum] = 1; destructors[keynum] = destructor; LeaveCriticalSection(&key_lock); err = 0; #else /* POSIX */ err = k5_mutex_lock(&key_lock); if (err == 0) { assert(destructors_set[keynum] == 0); destructors_set[keynum] = 1; destructors[keynum] = destructor; err = k5_mutex_unlock(&key_lock); } #endif return 0; }
void krb5int_thread_detach_hook (void) { /* XXX Memory leak here! Need to destroy all TLS objects we know about for this thread. */ struct tsd_block *t; int i, err; err = CALL_INIT_FUNCTION(krb5int_thread_support_init); if (err) return; t = TlsGetValue(tls_idx); if (t == NULL) return; for (i = 0; i < K5_KEY_MAX; i++) { if (destructors_set[i] && destructors[i] && t->values[i]) { void *v = t->values[i]; t->values[i] = 0; (*destructors[i])(v); } } }
errcode_t KRB5_CALLCONV remove_error_table(const struct error_table *et) { struct et_list **ep, *e; if (CALL_INIT_FUNCTION(com_err_initialize)) return 0; k5_mutex_lock(&et_list_lock); /* Remove the entry that matches the error table instance. */ for (ep = &et_list; *ep; ep = &(*ep)->next) { if ((*ep)->table == et) { e = *ep; *ep = e->next; free(e); k5_mutex_unlock(&et_list_lock); return 0; } } k5_mutex_unlock(&et_list_lock); return ENOENT; }
kern_return_t k5_ipc_client_reply (mach_port_t in_reply_port, k5_ipc_inl_reply_t in_inl_reply, mach_msg_type_number_t in_inl_replyCnt, k5_ipc_ool_reply_t in_ool_reply, mach_msg_type_number_t in_ool_replyCnt) { kern_return_t err = KERN_SUCCESS; k5_ipc_connection_info cinfo = NULL; if (!err) { err = CALL_INIT_FUNCTION (k5_cli_ipc_thread_init); } if (!err) { cinfo = k5_getspecific (K5_KEY_IPC_CONNECTION_INFO); if (!cinfo || !cinfo->reply_stream) { err = EINVAL; } } if (!err) { if (in_inl_replyCnt) { err = k5_ipc_stream_write (cinfo->reply_stream, in_inl_reply, in_inl_replyCnt); } else if (in_ool_replyCnt) { err = k5_ipc_stream_write (cinfo->reply_stream, in_ool_reply, in_ool_replyCnt); } else { err = EINVAL; } } if (in_ool_replyCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_reply, in_ool_replyCnt); } return err; }
static boolean_t k5_ipc_reply_demux (mach_msg_header_t *request, mach_msg_header_t *reply) { boolean_t handled = 0; if (CALL_INIT_FUNCTION (k5_cli_ipc_thread_init) != 0) { return 0; } if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) { k5_ipc_connection_info cinfo = k5_getspecific (K5_KEY_IPC_CONNECTION_INFO); if (cinfo) { cinfo->server_died = 1; } handled = 1; /* server died */ } if (!handled) { handled = k5_ipc_reply_server (request, reply); } return handled; }
int krb5int_crypto_init(void) { return CALL_INIT_FUNCTION(cryptoint_initialize_library); }
errcode_t profile_open_file(const_profile_filespec_t filespec, prf_file_t *ret_prof) { prf_file_t prf; errcode_t retval; char *home_env = 0; prf_data_t data; char *expanded_filename; retval = CALL_INIT_FUNCTION(profile_library_initializer); if (retval) return retval; scan_shared_trees_unlocked(); prf = malloc(sizeof(struct _prf_file_t)); if (!prf) return ENOMEM; memset(prf, 0, sizeof(struct _prf_file_t)); prf->magic = PROF_MAGIC_FILE; if (filespec[0] == '~' && filespec[1] == '/') { home_env = getenv("HOME"); #ifdef HAVE_PWD_H if (home_env == NULL) { uid_t uid; struct passwd *pw, pwx; char pwbuf[BUFSIZ]; uid = getuid(); if (!k5_getpwuid_r(uid, &pwx, pwbuf, sizeof(pwbuf), &pw) && pw != NULL && pw->pw_dir[0] != 0) home_env = pw->pw_dir; } #endif } if (home_env) { if (asprintf(&expanded_filename, "%s%s", home_env, filespec + 1) < 0) expanded_filename = 0; } else expanded_filename = strdup(filespec); if (expanded_filename == 0) { free(prf); return ENOMEM; } retval = k5_mutex_lock(&g_shared_trees_mutex); if (retval) { free(expanded_filename); free(prf); scan_shared_trees_unlocked(); return retval; } scan_shared_trees_locked(); for (data = g_shared_trees; data; data = data->next) { if (!strcmp(data->filespec, expanded_filename) /* Check that current uid has read access. */ && r_access(data->filespec)) break; } if (data) { data->refcount++; (void) k5_mutex_unlock(&g_shared_trees_mutex); retval = profile_update_file_data(data); free(expanded_filename); prf->data = data; *ret_prof = prf; scan_shared_trees_unlocked(); return retval; } (void) k5_mutex_unlock(&g_shared_trees_mutex); data = profile_make_prf_data(expanded_filename); if (data == NULL) { free(prf); free(expanded_filename); return ENOMEM; } free(expanded_filename); prf->data = data; retval = k5_mutex_init(&data->lock); if (retval) { free(data); free(prf); return retval; } retval = profile_update_file(prf); if (retval) { profile_close_file(prf); return retval; } retval = k5_mutex_lock(&g_shared_trees_mutex); if (retval) { profile_close_file(prf); scan_shared_trees_unlocked(); return retval; } scan_shared_trees_locked(); data->flags |= PROFILE_FILE_SHARED; data->next = g_shared_trees; g_shared_trees = data; scan_shared_trees_locked(); (void) k5_mutex_unlock(&g_shared_trees_mutex); *ret_prof = prf; return 0; }
int com_err_finish_init() { return CALL_INIT_FUNCTION(com_err_initialize); }
/* Always-delayed initialization -- error table linkage, etc. */ krb5_error_code krb5int_initialize_library (void) { return CALL_INIT_FUNCTION(krb5int_lib_init); }
int krb5int_call_thread_support_init (void) { return CALL_INIT_FUNCTION(krb5int_thread_support_init); }
int32_t k5_ipc_send_request (const char *in_service_id, int32_t in_launch_server, k5_ipc_stream in_request_stream, k5_ipc_stream *out_reply_stream) { int err = 0; int32_t done = 0; int32_t try_count = 0; mach_port_t server_port = MACH_PORT_NULL; k5_ipc_connection_info cinfo = NULL; k5_ipc_connection connection = NULL; mach_port_t reply_port = MACH_PORT_NULL; const char *inl_request = NULL; /* char * so we can pass the buffer in directly */ mach_msg_type_number_t inl_request_length = 0; k5_ipc_ool_request_t ool_request = NULL; mach_msg_type_number_t ool_request_length = 0; if (!in_request_stream) { err = EINVAL; } if (!out_reply_stream ) { err = EINVAL; } if (!err) { err = CALL_INIT_FUNCTION (k5_cli_ipc_thread_init); } if (!err) { /* depending on how big the message is, use the fast inline buffer or * the slow dynamically allocated buffer */ mach_msg_type_number_t request_length = k5_ipc_stream_size (in_request_stream); if (request_length > K5_IPC_MAX_INL_MSG_SIZE) { /*dprintf ("%s choosing out of line buffer (size is %d)", * __FUNCTION__, request_length); */ err = vm_read (mach_task_self (), (vm_address_t) k5_ipc_stream_data (in_request_stream), request_length, (vm_address_t *) &ool_request, &ool_request_length); } else { /*dprintf ("%s choosing in line buffer (size is %d)", * __FUNCTION__, request_length); */ inl_request_length = request_length; inl_request = k5_ipc_stream_data (in_request_stream); } } if (!err) { cinfo = k5_getspecific (K5_KEY_IPC_CONNECTION_INFO); if (!cinfo) { err = k5_ipc_client_cinfo_allocate (&cinfo); if (!err) { err = k5_setspecific (K5_KEY_IPC_CONNECTION_INFO, cinfo); } } if (!err) { int i, found = 0; for (i = 0; i < KIPC_SERVICE_COUNT; i++) { if (!strcmp (in_service_id, cinfo->connections[i].service_id)) { found = 1; connection = &cinfo->connections[i]; break; } } if (!found) { err = EINVAL; } } } if (!err) { err = k5_ipc_client_lookup_server (in_service_id, in_launch_server, TRUE, &server_port); } if (!err) { err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &reply_port); } while (!err && !done) { if (!err && !MACH_PORT_VALID (connection->port)) { err = k5_ipc_client_create_client_connection (server_port, &connection->port); } if (!err) { err = k5_ipc_client_request (connection->port, reply_port, inl_request, inl_request_length, ool_request, ool_request_length); } if (err == MACH_SEND_INVALID_DEST) { if (try_count < 2) { try_count++; err = 0; } if (MACH_PORT_VALID (connection->port)) { mach_port_mod_refs (mach_task_self(), connection->port, MACH_PORT_RIGHT_SEND, -1 ); connection->port = MACH_PORT_NULL; } /* Look up server name again without using the cached copy */ err = k5_ipc_client_lookup_server (in_service_id, in_launch_server, FALSE, &server_port); } else { /* Talked to server, though we may have gotten an error */ done = 1; /* Because we use ",dealloc" ool_request will be freed by mach. * Don't double free it. */ ool_request = NULL; ool_request_length = 0; } } if (!err) { err = k5_ipc_stream_new (&cinfo->reply_stream); } if (!err) { mach_port_t old_notification_target = MACH_PORT_NULL; /* request no-senders notification so we know when server dies */ err = mach_port_request_notification (mach_task_self (), reply_port, MACH_NOTIFY_NO_SENDERS, 1, reply_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_notification_target); if (!err && old_notification_target != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), old_notification_target); } } if (!err) { cinfo->server_died = 0; err = mach_msg_server_once (k5_ipc_reply_demux, K5_IPC_MAX_MSG_SIZE, reply_port, MACH_MSG_TIMEOUT_NONE); if (!err && cinfo->server_died) { err = ENOTCONN; } } if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) { err = 0; /* If server is not running just return an empty stream. */ } if (!err) { *out_reply_stream = cinfo->reply_stream; cinfo->reply_stream = NULL; } if (reply_port != MACH_PORT_NULL) { mach_port_destroy (mach_task_self (), reply_port); } if (ool_request_length) { vm_deallocate (mach_task_self (), (vm_address_t) ool_request, ool_request_length); } if (cinfo && cinfo->reply_stream) { k5_ipc_stream_release (cinfo->reply_stream); cinfo->reply_stream = NULL; } return err; }
int k5_setspecific (k5_key_t keynum, void *value) { struct tsd_block *t; int err; err = CALL_INIT_FUNCTION(krb5int_thread_support_init); if (err) return err; assert(keynum >= 0 && keynum < K5_KEY_MAX); assert(destructors_set[keynum] == 1); #ifndef ENABLE_THREADS t = &tsd_no_threads; #elif defined(_WIN32) t = TlsGetValue(tls_idx); if (t == NULL) { int i; t = malloc(sizeof(*t)); if (t == NULL) return ENOMEM; for (i = 0; i < K5_KEY_MAX; i++) t->values[i] = 0; /* add to global linked list */ /* t->next = 0; */ err = TlsSetValue(tls_idx, t); if (!err) { free(t); return GetLastError(); } } #else /* POSIX */ if (K5_PTHREADS_LOADED) { t = pthread_getspecific(key); if (t == NULL) { int i; t = malloc(sizeof(*t)); if (t == NULL) return ENOMEM; for (i = 0; i < K5_KEY_MAX; i++) t->values[i] = 0; /* add to global linked list */ t->next = 0; err = pthread_setspecific(key, t); if (err) { free(t); return err; } } } else { t = GET_NO_PTHREAD_TSD(); } #endif t->values[keynum] = value; return 0; }
int gssint_mechglue_initialize_library(void) { return CALL_INIT_FUNCTION(gssint_mechglue_init); }
const char * KRB5_CALLCONV error_message(long code) /*@modifies internalState@*/ { unsigned long offset; unsigned long l_offset; struct et_list *et; struct dynamic_et_list *det; unsigned long table_num; int started = 0; unsigned int divisor = 100; char *cp, *cp1; const struct error_table *table; int merr; l_offset = (unsigned long)code & ((1<<ERRCODE_RANGE)-1); offset = l_offset; table_num = ((unsigned long)code - l_offset) & ERRCODE_MAX; if (table_num == 0 #ifdef __sgi /* Irix 6.5 uses a much bigger table than other UNIX systems I've looked at, but the table is sparse. The sparse entries start around 500, but sys_nerr is only 152. */ || (code > 0 && code <= 1600) #endif ) { if (code == 0) goto oops; /* This could trip if int is 16 bits. */ if ((unsigned long)(int)code != (unsigned long)code) abort (); #ifdef HAVE_STRERROR_R cp = get_thread_buffer(); if (cp && strerror_r((int) code, cp, ET_EBUFSIZ) == 0) return cp; #endif #ifdef HAVE_STRERROR cp = strerror((int) code); if (cp) return cp; #elif defined HAVE_SYS_ERRLIST if (offset < sys_nerr) return(sys_errlist[offset]); #endif goto oops; } if (CALL_INIT_FUNCTION(com_err_initialize)) return 0; merr = k5_mutex_lock(&et_list_lock); if (merr) goto oops; dprintf (("scanning static list for %x\n", table_num)); for (et = _et_list; et != NULL; et = et->next) { if (et->table == NULL) continue; dprintf (("\t%x = %s\n", et->table->base & ERRCODE_MAX, et->table->msgs[0])); if ((et->table->base & ERRCODE_MAX) == table_num) { table = et->table; goto found; } } dprintf (("scanning dynamic list for %x\n", table_num)); for (det = et_list_dynamic; det != NULL; det = det->next) { dprintf (("\t%x = %s\n", det->table->base & ERRCODE_MAX, det->table->msgs[0])); if ((det->table->base & ERRCODE_MAX) == table_num) { table = det->table; goto found; } } goto no_table_found; found: k5_mutex_unlock(&et_list_lock); dprintf (("found it!\n")); /* This is the right table */ /* This could trip if int is 16 bits. */ if ((unsigned long)(unsigned int)offset != offset) goto no_table_found; if (table->n_msgs <= (unsigned int) offset) goto no_table_found; return table->msgs[offset]; no_table_found: k5_mutex_unlock(&et_list_lock); #if defined(_WIN32) /* * WinSock errors exist in the 10000 and 11000 ranges * but might not appear if WinSock is not initialized */ if (code >= WSABASEERR && code < WSABASEERR + 1100) { table_num = 0; offset = code; divisor = WSABASEERR; } #endif #ifdef _WIN32 { LPVOID msgbuf; if (! FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL /* lpSource */, (DWORD) code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &msgbuf, (DWORD) 0 /*sizeof(buffer)*/, NULL /* va_list */ )) { /* * WinSock errors exist in the 10000 and 11000 ranges * but might not appear if WinSock is not initialized */ if (code >= WSABASEERR && code < WSABASEERR + 1100) { table_num = 0; offset = code; divisor = 10000; } goto oops; } else { char *buffer; cp = get_thread_buffer(); if (cp == NULL) return "Unknown error code"; buffer = cp; strncpy(buffer, msgbuf, ET_EBUFSIZ); buffer[ET_EBUFSIZ-1] = '\0'; cp = buffer + strlen(buffer) - 1; if (*cp == '\n') *cp-- = '\0'; if (*cp == '\r') *cp-- = '\0'; if (*cp == '.') *cp-- = '\0'; LocalFree(msgbuf); return buffer; } } #endif oops: cp = get_thread_buffer(); if (cp == NULL) return "Unknown error code"; cp1 = cp; strlcpy(cp, "Unknown code ", ET_EBUFSIZ); cp += sizeof("Unknown code ") - 1; if (table_num != 0L) { (void) error_table_name_r(table_num, cp); while (*cp != '\0') cp++; *cp++ = ' '; } while (divisor > 1) { if (started != 0 || offset >= divisor) { *cp++ = '0' + offset / divisor; offset %= divisor; started++; } divisor /= 10; } *cp++ = '0' + offset; *cp = '\0'; return(cp1); }
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; }