AUTH * authgss_create(CLIENT *clnt, gss_name_t name, struct rpc_gss_sec *sec) { AUTH *auth, *save_auth; struct rpc_gss_data *gd; OM_uint32 min_stat = 0; log_debug("in authgss_create()"); memset(&rpc_createerr, 0, sizeof(rpc_createerr)); if ((auth = calloc(sizeof(*auth), 1)) == NULL) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = ENOMEM; return (NULL); } if ((gd = calloc(sizeof(*gd), 1)) == NULL) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = ENOMEM; free(auth); return (NULL); } #ifdef DEBUG fprintf(stderr, "authgss_create: name is %p\n", name); #endif if (name != GSS_C_NO_NAME) { if (gss_duplicate_name(&min_stat, name, &gd->name) != GSS_S_COMPLETE) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = ENOMEM; free(auth); return (NULL); } } else gd->name = name; #ifdef DEBUG fprintf(stderr, "authgss_create: gd->name is %p\n", gd->name); #endif gd->clnt = clnt; gd->ctx = GSS_C_NO_CONTEXT; gd->sec = *sec; gd->gc.gc_v = RPCSEC_GSS_VERSION; gd->gc.gc_proc = RPCSEC_GSS_INIT; gd->gc.gc_svc = gd->sec.svc; auth->ah_ops = &authgss_ops; auth->ah_private = (caddr_t)gd; save_auth = clnt->cl_auth; clnt->cl_auth = auth; if (!authgss_refresh(auth)) auth = NULL; else auth_get(auth); /* Reference for caller */ clnt->cl_auth = save_auth; return (auth); }
/* * 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_nseccreate(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) { __warnx(TIRPC_DEBUG_FLAG_AUTH, "authdes_pk_nseccreate: out of memory"); return (NULL); } ad = ALLOC(struct ad_private); if (ad == NULL) { __warnx(TIRPC_DEBUG_FLAG_AUTH, "authdes_pk_nseccreate: 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) { __warnx(TIRPC_DEBUG_FLAG_AUTH, "authdes_nseccreate: out of memory"); goto failed; } if (timehost != NULL) { ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1); if (ad->ad_timehost == NULL) { __warnx(TIRPC_DEBUG_FLAG_AUTH, "authdes_nseccreate: 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) { __warnx(TIRPC_DEBUG_FLAG_AUTH, "authdes_nseccreate: 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 */ auth_get(auth); /* Reference for caller */ 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); }