299
299
if (clp->krb5_poll_index != -1)
300
300
memset(&pollarray[clp->krb5_poll_index], 0,
301
301
sizeof(struct pollfd));
302
if (clp->spkm3_poll_index != -1)
303
memset(&pollarray[clp->spkm3_poll_index], 0,
304
sizeof(struct pollfd));
305
302
if (clp->gssd_poll_index != -1)
306
303
memset(&pollarray[clp->gssd_poll_index], 0,
307
304
sizeof(struct pollfd));
308
305
if (clp->dir_fd != -1) close(clp->dir_fd);
309
306
if (clp->krb5_fd != -1) close(clp->krb5_fd);
310
if (clp->spkm3_fd != -1) close(clp->spkm3_fd);
311
307
if (clp->gssd_fd != -1) close(clp->gssd_fd);
312
308
free(clp->dirname);
313
309
free(clp->servicename);
355
349
snprintf(name, sizeof(name), "%s/krb5", clp->dirname);
356
350
clp->krb5_fd = open(name, O_RDWR);
358
if (clp->spkm3_fd == -1) {
359
snprintf(name, sizeof(name), "%s/spkm3", clp->dirname);
360
clp->spkm3_fd = open(name, O_RDWR);
363
353
/* If we opened a gss-specific pipe, let's try opening
364
354
* the new upcall pipe again. If we succeed, close
365
355
* gss-specific pipe(s).
367
if (clp->krb5_fd != -1 || clp->spkm3_fd != -1) {
357
if (clp->krb5_fd != -1) {
368
358
clp->gssd_fd = open(gname, O_RDWR);
369
359
if (clp->gssd_fd != -1) {
370
360
if (clp->krb5_fd != -1)
371
361
close(clp->krb5_fd);
372
362
clp->krb5_fd = -1;
373
if (clp->spkm3_fd != -1)
374
close(clp->spkm3_fd);
380
if ((clp->krb5_fd == -1) && (clp->spkm3_fd == -1) &&
381
(clp->gssd_fd == -1))
367
if ((clp->krb5_fd == -1) && (clp->gssd_fd == -1))
383
369
snprintf(info_file_name, sizeof(info_file_name), "%s/info",
431
417
pollarray[clp->krb5_poll_index].events |= POLLIN;
434
if ((clp->spkm3_fd != -1) && (clp->spkm3_poll_index == -1)) {
435
if (get_poll_index(&clp->spkm3_poll_index)) {
436
printerr(0, "ERROR: Too many spkm3 clients\n");
439
pollarray[clp->spkm3_poll_index].fd = clp->spkm3_fd;
440
pollarray[clp->spkm3_poll_index].events |= POLLIN;
839
816
sec.mech = (gss_OID)&krb5oid;
840
817
sec.req_flags = GSS_C_MUTUAL_FLAG;
842
else if (authtype == AUTHTYPE_SPKM3) {
843
sec.mech = (gss_OID)&spkm3oid;
844
/* XXX sec.req_flags = GSS_C_ANON_FLAG;
845
* Need a way to switch....
847
sec.req_flags = GSS_C_MUTUAL_FLAG;
850
820
printerr(0, "ERROR: Invalid authentication type (%d) "
851
821
"in create_auth_rpc_client\n", authtype);
919
889
auth = authgss_create_default(rpc_clnt, clp->servicename, &sec);
921
891
/* Our caller should print appropriate message */
922
printerr(2, "WARNING: Failed to create %s context for "
892
printerr(2, "WARNING: Failed to create krb5 context for "
923
893
"user with uid %d for server %s\n",
924
(authtype == AUTHTYPE_KRB5 ? "krb5":"spkm3"),
925
894
uid, clp->servername);
922
user_cachedir(char *dirname, uid_t uid)
927
if ((pw = getpwuid(uid)) == NULL) {
928
printerr(0, "user_cachedir: Failed to find '%d' uid"
929
" for cache directory\n");
932
ptr = malloc(strlen(dirname)+strlen(pw->pw_name)+2);
934
sprintf(ptr, "%s/%s", dirname, pw->pw_name);
953
939
* this code uses the userland rpcsec gss library to create a krb5
954
940
* context on behalf of the kernel
1006
992
service == NULL)) {
1007
993
/* Tell krb5 gss which credentials cache to use */
1008
994
for (dirname = ccachesearch; *dirname != NULL; dirname++) {
1009
err = gssd_setup_krb5_user_gss_ccache(uid, clp->servername, *dirname);
995
/* See if the user name is needed */
996
if (strncmp(*dirname, GSSD_USER_CRED_DIR,
997
strlen(GSSD_USER_CRED_DIR)) == 0) {
998
userdir = user_cachedir(*dirname, uid);
1005
err = gssd_setup_krb5_user_gss_ccache(uid, clp->servername, dir);
1010
1011
if (err == -EKEYEXPIRED)
1011
1012
downcall_err = -EKEYEXPIRED;
1107
* this code uses the userland rpcsec gss library to create an spkm3
1108
* context on behalf of the kernel
1111
process_spkm3_upcall(struct clnt_info *clp, uid_t uid, int fd)
1113
CLIENT *rpc_clnt = NULL;
1115
struct authgss_private_data pd;
1116
gss_buffer_desc token;
1118
printerr(2, "handling spkm3 upcall (%s)\n", clp->dirname);
1123
if (create_auth_rpc_client(clp, &rpc_clnt, &auth, uid, AUTHTYPE_SPKM3)) {
1124
printerr(0, "WARNING: Failed to create spkm3 context for "
1125
"user with uid %d\n", uid);
1126
goto out_return_error;
1129
if (!authgss_get_private_data(auth, &pd)) {
1130
printerr(0, "WARNING: Failed to obtain authentication "
1131
"data for user with uid %d for server %s\n",
1132
uid, clp->servername);
1133
goto out_return_error;
1136
if (serialize_context_for_kernel(pd.pd_ctx, &token, &spkm3oid, NULL)) {
1137
printerr(0, "WARNING: Failed to serialize spkm3 context for "
1138
"user with uid %d for server\n",
1139
uid, clp->servername);
1140
goto out_return_error;
1143
do_downcall(fd, uid, &pd, &token);
1151
clnt_destroy(rpc_clnt);
1155
do_error_downcall(fd, uid, -1);
1160
1108
handle_krb5_upcall(struct clnt_info *clp)
1174
handle_spkm3_upcall(struct clnt_info *clp)
1178
if (read(clp->spkm3_fd, &uid, sizeof(uid)) < (ssize_t)sizeof(uid)) {
1179
printerr(0, "WARNING: failed reading uid from spkm3 "
1180
"upcall pipe: %s\n", strerror(errno));
1184
return process_spkm3_upcall(clp, uid, clp->spkm3_fd);
1188
1122
handle_gssd_upcall(struct clnt_info *clp)
1293
1227
if (strcmp(mech, "krb5") == 0)
1294
1228
process_krb5_upcall(clp, uid, clp->gssd_fd, target, service);
1295
else if (strcmp(mech, "spkm3") == 0)
1296
process_spkm3_upcall(clp, uid, clp->gssd_fd);
1298
1230
printerr(0, "WARNING: handle_gssd_upcall: "
1299
1231
"received unknown gss mech '%s'\n", mech);