/* * Slightly modified version of authdessec_create which takes the public key * of the server principal as an argument. This spares us a call to * getpublickey() which in the nameserver context can cause a deadlock. */ AUTH * authdes_pk_seccreate(const char *servername, netobj *pkey, u_int window, const char *timehost, const des_block *ckey, nis_server *srvr) { AUTH *auth; struct ad_private *ad; char namebuf[MAXNETNAMELEN+1]; /* * Allocate everything now */ auth = ALLOC(AUTH); if (auth == NULL) { syslog(LOG_ERR, "authdes_pk_seccreate: out of memory"); return (NULL); } ad = ALLOC(struct ad_private); if (ad == NULL) { syslog(LOG_ERR, "authdes_pk_seccreate: out of memory"); goto failed; } ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */ ad->ad_timehost = NULL; ad->ad_netid = NULL; ad->ad_uaddr = NULL; ad->ad_nis_srvr = NULL; ad->ad_timediff.tv_sec = 0; ad->ad_timediff.tv_usec = 0; memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len); if (!getnetname(namebuf)) goto failed; ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf)); ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1); ad->ad_servernamelen = strlen(servername); ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1); if (ad->ad_fullname == NULL || ad->ad_servername == NULL) { syslog(LOG_ERR, "authdes_seccreate: out of memory"); goto failed; } if (timehost != NULL) { ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1); if (ad->ad_timehost == NULL) { syslog(LOG_ERR, "authdes_seccreate: out of memory"); goto failed; } memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1); ad->ad_dosync = TRUE; } else if (srvr != NULL) { ad->ad_nis_srvr = srvr; /* transient */ ad->ad_dosync = TRUE; } else { ad->ad_dosync = FALSE; } memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1); memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1); ad->ad_window = window; if (ckey == NULL) { if (key_gendes(&auth->ah_key) < 0) { syslog(LOG_ERR, "authdes_seccreate: keyserv(1m) is unable to generate session key"); goto failed; } } else { auth->ah_key = *ckey; } /* * Set up auth handle */ auth->ah_cred.oa_flavor = AUTH_DES; auth->ah_verf.oa_flavor = AUTH_DES; auth->ah_ops = authdes_ops(); auth->ah_private = (caddr_t)ad; if (!authdes_refresh(auth, NULL)) { goto failed; } ad->ad_nis_srvr = NULL; /* not needed any longer */ return (auth); failed: if (auth) FREE(auth, sizeof (AUTH)); if (ad) { if (ad->ad_fullname) FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); if (ad->ad_servername) FREE(ad->ad_servername, ad->ad_servernamelen + 1); if (ad->ad_timehost) FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); if (ad->ad_netid) FREE(ad->ad_netid, strlen(ad->ad_netid) + 1); if (ad->ad_uaddr) FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); FREE(ad, sizeof (struct ad_private)); } return (NULL); }
AUTH * authdes_pk_create (const char *servername, netobj *pkey, u_int window, struct sockaddr *syncaddr, des_block *ckey) { AUTH *auth; struct ad_private *ad; char namebuf[MAXNETNAMELEN + 1]; /* * Allocate everything now */ auth = ALLOC (AUTH); ad = ALLOC (struct ad_private); if (auth == NULL || ad == NULL) { debug ("authdes_create: out of memory"); goto failed; } memset (ad, 0, sizeof (struct ad_private)); memcpy (ad->ad_pkey, pkey->n_bytes, pkey->n_len); if (!getnetname (namebuf)) goto failed; ad->ad_fullnamelen = RNDUP (strlen (namebuf)); ad->ad_fullname = mem_alloc (ad->ad_fullnamelen + 1); ad->ad_servernamelen = strlen (servername); ad->ad_servername = mem_alloc (ad->ad_servernamelen + 1); if (ad->ad_fullname == NULL || ad->ad_servername == NULL) { debug ("authdes_create: out of memory"); goto failed; } /* * Set up private data */ memcpy (ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1); memcpy (ad->ad_servername, servername, ad->ad_servernamelen + 1); ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0; if (syncaddr != NULL) { ad->ad_syncaddr = *syncaddr; ad->ad_dosync = TRUE; } else ad->ad_dosync = FALSE; ad->ad_window = window; if (ckey == NULL) { if (key_gendes (&auth->ah_key) < 0) { debug ("authdes_create: unable to gen conversation key"); goto failed; } } else auth->ah_key = *ckey; /* * Set up auth handle */ auth->ah_cred.oa_flavor = AUTH_DES; auth->ah_verf.oa_flavor = AUTH_DES; auth->ah_ops = (struct auth_ops *) &authdes_ops; auth->ah_private = (caddr_t) ad; if (!authdes_refresh (auth)) goto failed; return auth; failed: if (auth != NULL) FREE (auth, sizeof (AUTH)); if (ad != NULL) { if (ad->ad_fullname != NULL) FREE (ad->ad_fullname, ad->ad_fullnamelen + 1); if (ad->ad_servername != NULL) FREE (ad->ad_servername, ad->ad_servernamelen + 1); FREE (ad, sizeof (struct ad_private)); } return NULL; }