void owl_zephyr_initialize() { int ret; struct servent *sp; struct sockaddr_in sin; ZNotice_t req; Code_t code; owl_dispatch *dispatch; /* * Code modified from libzephyr's ZhmStat.c * * Modified to add the fd to our select loop, rather than hanging * until we get an ack. */ if ((ret = ZOpenPort(NULL)) != ZERR_NONE) { owl_function_error("Error opening Zephyr port: %s", error_message(ret)); return; } (void) memset((char *)&sin, 0, sizeof(struct sockaddr_in)); sp = getservbyname(HM_SVCNAME, "udp"); sin.sin_port = (sp) ? sp->s_port : HM_SVC_FALLBACK; sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); (void) memset((char *)&req, 0, sizeof(req)); req.z_kind = STAT; req.z_port = 0; req.z_class = HM_STAT_CLASS; req.z_class_inst = HM_STAT_CLIENT; req.z_opcode = HM_GIMMESTATS; req.z_sender = ""; req.z_recipient = ""; req.z_default_format = ""; req.z_message_len = 0; if ((code = ZSetDestAddr(&sin)) != ZERR_NONE) { owl_function_error("Initializing Zephyr: %s", error_message(code)); return; } if ((code = ZSendNotice(&req, ZNOAUTH)) != ZERR_NONE) { owl_function_error("Initializing Zephyr: %s", error_message(code)); return; } dispatch = owl_malloc(sizeof(*dispatch)); dispatch->fd = ZGetFD(); dispatch->cfunc = owl_zephyr_finish_initialization; dispatch->destroy = (void(*)(owl_dispatch*))owl_free; owl_select_add_dispatch(dispatch); }
int main(int argc, char *argv[]) { Code_t ret; char hostname[NS_MAXDNAME]; int optchar; struct servent *sp; if ((ret = ZInitialize()) != ZERR_NONE) { com_err("zstat", ret, "initializing"); exit(-1); } if ((ret = ZOpenPort((u_short *)0)) != ZERR_NONE) { com_err("zstat", ret, "opening port"); exit(-1); } while ((optchar = getopt(argc, argv, "sh")) != EOF) { switch(optchar) { case 's': serveronly++; break; case 'h': hmonly++; break; case '?': default: usage(argv[0]); exit(1); } } if (serveronly && hmonly) { fprintf(stderr,"Only one of -s and -h may be specified\n"); exit(1); } sp = getservbyname(SERVER_SVCNAME,"udp"); srv_port = (sp) ? sp->s_port : SERVER_SVC_FALLBACK; if (optind == argc) { if (gethostname(hostname, sizeof(hostname)) < 0) { com_err("zstat",errno,"while finding hostname"); exit(-1); } do_stat(hostname); exit(0); } for (;optind<argc;optind++) do_stat(argv[optind]); exit(0); }
void owl_zephyr_initialize(void) { Code_t ret; struct servent *sp; struct sockaddr_in sin; ZNotice_t req; GIOChannel *channel; /* * Code modified from libzephyr's ZhmStat.c * * Modified to add the fd to our select loop, rather than hanging * until we get an ack. */ if ((ret = ZOpenPort(NULL)) != ZERR_NONE) { owl_function_error("Error opening Zephyr port: %s", error_message(ret)); return; } (void) memset(&sin, 0, sizeof(struct sockaddr_in)); sp = getservbyname(HM_SVCNAME, "udp"); sin.sin_port = (sp) ? sp->s_port : HM_SVC_FALLBACK; sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); (void) memset(&req, 0, sizeof(req)); req.z_kind = STAT; req.z_port = 0; req.z_class = zstr(HM_STAT_CLASS); req.z_class_inst = zstr(HM_STAT_CLIENT); req.z_opcode = zstr(HM_GIMMESTATS); req.z_sender = zstr(""); req.z_recipient = zstr(""); req.z_default_format = zstr(""); req.z_message_len = 0; if ((ret = ZSetDestAddr(&sin)) != ZERR_NONE) { owl_function_error("Initializing Zephyr: %s", error_message(ret)); return; } if ((ret = ZSendNotice(&req, ZNOAUTH)) != ZERR_NONE) { owl_function_error("Initializing Zephyr: %s", error_message(ret)); return; } channel = g_io_channel_unix_new(ZGetFD()); g_io_add_watch(channel, G_IO_IN | G_IO_ERR | G_IO_HUP, &owl_zephyr_finish_initialization, NULL); g_io_channel_unref(channel); }
void owl_zephyr_finish_initialization(const owl_io_dispatch *d, void *data) { Code_t code; char *perl; GSource *event_source; owl_select_remove_io_dispatch(d); ZClosePort(); if ((code = ZInitialize()) != ZERR_NONE) { owl_function_error("Initializing Zephyr: %s", error_message(code)); return; } if ((code = ZOpenPort(NULL)) != ZERR_NONE) { owl_function_error("Initializing Zephyr: %s", error_message(code)); return; } event_source = owl_zephyr_event_source_new(ZGetFD()); g_source_attach(event_source, NULL); g_source_unref(event_source); owl_global_set_havezephyr(&g); if(g.load_initial_subs) { owl_zephyr_load_initial_subs(); } while(deferred_subs != NULL) { owl_sub_list *subs = deferred_subs->data; owl_function_debugmsg("Loading %d deferred subs.", subs->nsubs); owl_zephyr_loadsubs_helper(subs->subs, subs->nsubs); deferred_subs = g_list_delete_link(deferred_subs, deferred_subs); g_free(subs); } /* zlog in if we need to */ if (owl_global_is_startuplogin(&g)) { owl_function_debugmsg("startup: doing zlog in"); owl_zephyr_zlog_in(); } /* check pseudo-logins if we need to */ if (owl_global_is_pseudologins(&g)) { owl_function_debugmsg("startup: checking pseudo-logins"); owl_function_zephyr_buddy_check(0); } perl = owl_perlconfig_execute("BarnOwl::Zephyr::_zephyr_startup()"); g_free(perl); }
void owl_zephyr_finish_initialization(owl_dispatch *d) { Code_t code; owl_select_remove_dispatch(d->fd); ZClosePort(); if ((code = ZInitialize()) != ZERR_NONE) { owl_function_error("Initializing Zephyr: %s", error_message(code)); return; } if ((code = ZOpenPort(NULL)) != ZERR_NONE) { owl_function_error("Initializing Zephyr: %s", error_message(code)); return; } d = owl_malloc(sizeof(owl_dispatch)); d->fd = ZGetFD(); d->cfunc = &owl_zephyr_process_events; d->destroy = NULL; owl_select_add_dispatch(d); owl_global_set_havezephyr(&g); if(g.load_initial_subs) { owl_zephyr_load_initial_subs(); } while(deferred_subs != NULL) { owl_sub_list *subs = deferred_subs->data; owl_function_debugmsg("Loading %d deferred subs.", subs->nsubs); owl_zephyr_loadsubs_helper(subs->subs, subs->nsubs); deferred_subs = g_list_delete_link(deferred_subs, deferred_subs); owl_free(subs); } /* zlog in if we need to */ if (owl_global_is_startuplogin(&g)) { owl_function_debugmsg("startup: doing zlog in"); owl_zephyr_zlog_in(); } }
Code_t ZRequestLocations(char *user, register ZAsyncLocateData_t *zald, ZNotice_Kind_t kind, /* UNSAFE, UNACKED, or ACKED */ Z_AuthProc auth) { int retval; ZNotice_t notice; if (ZGetFD() < 0) if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE) return (retval); (void) memset((char *)¬ice, 0, sizeof(notice)); notice.z_kind = kind; notice.z_port = __Zephyr_port; notice.z_class = LOCATE_CLASS; notice.z_class_inst = user; notice.z_opcode = LOCATE_LOCATE; notice.z_sender = 0; notice.z_recipient = ""; notice.z_default_format = ""; notice.z_message_len = 0; if ((retval = ZSendNotice(¬ice, auth)) != ZERR_NONE) return(retval); if ((zald->user = (char *) malloc(strlen(user)+1)) == NULL) { return(ENOMEM); } if ((zald->version = (char *) malloc(strlen(notice.z_version)+1)) == NULL) { free(zald->user); return(ENOMEM); } zald->uid = notice.z_multiuid; strcpy(zald->user,user); strcpy(zald->version,notice.z_version); return(ZERR_NONE); }
Code_t ZLoadSession(char *buffer, int len) { #ifdef HAVE_KRB5 struct _Z_SessionKey *key; uint32_t num_keys, keylength; krb5_enctype enctype; int i; #endif Code_t ret; uint16_t version, port; if (len < 2) return (EINVAL); version = ntohs(*((uint16_t *) buffer)); buffer += 2; len -= 2; if (version != SESSION_VERSION) return (EINVAL); if (len < 2) return (EINVAL); port = ntohs(*((uint16_t *) buffer)); buffer += 2; len -= 2; if ((ret = ZOpenPort(&port)) != ZERR_NONE) return ret; #ifdef HAVE_KRB5 if (len < 4) return (EINVAL); num_keys = ntohl(*((uint32_t *) buffer)); buffer += 4; len -= 4; for (i = 0; i < num_keys; i++) { key = (struct _Z_SessionKey *)malloc(sizeof(struct _Z_SessionKey)); if (!key) return (ENOMEM); if (len < 4) { free(key); return (EINVAL); } enctype = ntohl(*((uint32_t *) buffer)); buffer += 4; len -= 4; if (len < 4) { free(key); return (EINVAL); } keylength = ntohl(*((uint32_t *) buffer)); buffer += 4; len -= 4; if (len < keylength) { free(key); return (EINVAL); } ret = krb5_init_keyblock(Z_krb5_ctx, enctype, keylength, &key->keyblock); if (ret) { free(key); return ret; } memcpy((char *)key->keyblock->contents, buffer, keylength); buffer += keylength; len -= keylength; /* Just set recent times. It means we might not be able to retire the keys, but that's fine. */ key->send_time = time(NULL); key->first_use = time(NULL); /* Prepend to the key list. */ key->prev = NULL; key->next = Z_keys_head; if (Z_keys_head) Z_keys_head->prev = key; Z_keys_head = key; if (!Z_keys_tail) Z_keys_tail = key; } #endif if (len) return (EINVAL); return (ZERR_NONE); }
Code_t ZInitialize() { struct servent *hmserv; struct hostent *hostent; char addr[4], hostname[MAXHOSTNAMELEN]; struct in_addr servaddr; struct sockaddr_in sin; int s; socklen_t sinsize = sizeof(sin); Code_t code; ZNotice_t notice; #ifdef ZEPHYR_USES_KERBEROS char *krealm = NULL; int krbval; char d1[ANAME_SZ], d2[INST_SZ]; /* initialize_krb_error_table(); */ #endif initialize_zeph_error_table(); (void) memset((char *)&__HM_addr, 0, sizeof(__HM_addr)); __HM_addr.sin_family = AF_INET; /* Set up local loopback address for HostManager */ addr[0] = 127; addr[1] = 0; addr[2] = 0; addr[3] = 1; hmserv = (struct servent *)getservbyname(HM_SVCNAME, "udp"); __HM_addr.sin_port = (hmserv) ? hmserv->s_port : HM_SVC_FALLBACK; (void) memcpy((char *)&__HM_addr.sin_addr, addr, 4); __HM_set = 0; /* Initialize the input queue */ __Q_Tail = NULL; __Q_Head = NULL; /* if the application is a server, there might not be a zhm. The code will fall back to something which might not be "right", but this is is ok, since none of the servers call krb_rd_req. */ servaddr.s_addr = INADDR_NONE; if (! __Zephyr_server) { if ((code = ZOpenPort(NULL)) != ZERR_NONE) return(code); if ((code = ZhmStat(NULL, ¬ice)) != ZERR_NONE) return(code); ZClosePort(); /* the first field, which is NUL-terminated, is the server name. If this code ever support a multiplexing zhm, this will have to be made smarter, and probably per-message */ #ifdef ZEPHYR_USES_KERBEROS krealm = krb_realmofhost(notice.z_message); #endif hostent = gethostbyname(notice.z_message); if (hostent && hostent->h_addrtype == AF_INET) memcpy(&servaddr, hostent->h_addr, sizeof(servaddr)); ZFreeNotice(¬ice); } #ifdef ZEPHYR_USES_KERBEROS if (krealm) { g_strlcpy(__Zephyr_realm, krealm, REALM_SZ); } else if ((krb_get_tf_fullname(TKT_FILE, d1, d2, __Zephyr_realm) != KSUCCESS) && ((krbval = krb_get_lrealm(__Zephyr_realm, 1)) != KSUCCESS)) { return (krbval); } #else g_strlcpy(__Zephyr_realm, "local-realm", REALM_SZ); #endif __My_addr.s_addr = INADDR_NONE; if (servaddr.s_addr != INADDR_NONE) { /* Try to get the local interface address by connecting a UDP * socket to the server address and getting the local address. * Some broken operating systems (e.g. Solaris 2.0-2.5) yield * INADDR_ANY (zero), so we have to check for that. */ s = socket(AF_INET, SOCK_DGRAM, 0); if (s != -1) { memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; memcpy(&sin.sin_addr, &servaddr, sizeof(servaddr)); sin.sin_port = HM_SRV_SVC_FALLBACK; if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == 0 && getsockname(s, (struct sockaddr *) &sin, &sinsize) == 0 && sin.sin_addr.s_addr != 0) memcpy(&__My_addr, &sin.sin_addr, sizeof(__My_addr)); close(s); } } if (__My_addr.s_addr == INADDR_NONE) { /* We couldn't figure out the local interface address by the * above method. Try by resolving the local hostname. (This * is a pretty broken thing to do, and unfortunately what we * always do on server machines.) */ if (gethostname(hostname, sizeof(hostname)) == 0) { hostent = gethostbyname(hostname); if (hostent && hostent->h_addrtype == AF_INET) memcpy(&__My_addr, hostent->h_addr, sizeof(__My_addr)); } } /* If the above methods failed, zero out __My_addr so things will * sort of kind of work. */ if (__My_addr.s_addr == INADDR_NONE) __My_addr.s_addr = 0; /* Get the sender so we can cache it */ (void) ZGetSender(); return (ZERR_NONE); }