@@ -841,7 +841,8 @@ create_auth_rpc_client(struct clnt_info *clp,
AUTH **auth_return,
uid_t uid,
int authtype,
- gss_cred_id_t cred)
+ gss_cred_id_t cred,
+ int svc /* rpc_gss_svc_t */ )
{
CLIENT *rpc_clnt = NULL;
struct rpc_gss_sec sec;
@@ -855,7 +856,7 @@ create_auth_rpc_client(struct clnt_info *clp,
socklen_t salen;
sec.qop = GSS_C_QOP_DEFAULT;
- sec.svc = RPCSEC_GSS_SVC_NONE;
+ sec.svc = svc;
sec.cred = cred;
sec.req_flags = 0;
if (authtype == AUTHTYPE_KRB5) {
@@ -1029,7 +1030,7 @@ change_identity(uid_t uid)
*/
static void
process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
- char *service)
+ char *service, int svc)
{
CLIENT *rpc_clnt = NULL;
AUTH *auth = NULL;
@@ -1113,7 +1114,7 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
err = gssd_acquire_user_cred(&gss_cred);
if (!err)
create_resp = create_auth_rpc_client(clp, tgtname, &rpc_clnt, &auth, uid,
- AUTHTYPE_KRB5, gss_cred);
+ AUTHTYPE_KRB5, gss_cred, svc);
/* if create_auth_rplc_client fails try the traditional method of
* trolling for credentials */
for (dirname = ccachesearch; create_resp != 0 && *dirname != NULL; dirname++) {
@@ -1122,7 +1123,7 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
downcall_err = -EKEYEXPIRED;
else if (!err)
create_resp = create_auth_rpc_client(clp, tgtname, &rpc_clnt, &auth, uid,
- AUTHTYPE_KRB5, GSS_C_NO_CREDENTIAL);
+ AUTHTYPE_KRB5, GSS_C_NO_CREDENTIAL, svc);
}
}
if (create_resp != 0) {
@@ -1148,7 +1149,7 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
if ((create_auth_rpc_client(clp, tgtname, &rpc_clnt,
&auth, uid,
AUTHTYPE_KRB5,
- GSS_C_NO_CREDENTIAL)) == 0) {
+ GSS_C_NO_CREDENTIAL, svc)) == 0) {
/* Success! */
success++;
break;
@@ -1243,7 +1244,8 @@ handle_krb5_upcall(struct clnt_info *clp)
return;
}
- process_krb5_upcall(clp, uid, clp->krb5_fd, NULL, NULL);
+ process_krb5_upcall(clp, uid, clp->krb5_fd, NULL, NULL,
+ RPCSEC_GSS_SVC_NONE);
}
void
@@ -1251,6 +1253,7 @@ handle_gssd_upcall(struct clnt_info *clp)
{
uid_t uid;
char *lbuf = NULL;
+ int svc = 0; /* rpc_gss_service_t */
int lbuflen = 0;
char *p;
char *mech = NULL;
@@ -1300,6 +1303,21 @@ handle_gssd_upcall(struct clnt_info *clp)
goto out;
}
+ /* read rpc_gss_service_t */
+ if ((p = strstr(lbuf, "svc=")) != NULL) {
+ if (sscanf(p, "svc=%d", &svc) != 1) {
+ printerr(0, "WARNING: handle_gssd_upcall: "
+ "failed to parse svc "
+ "in upcall string '%s'\n", lbuf);
+ goto out;
+ }
+ } else {
+ printerr(0, "WARNING: handle_gssd_upcall: "
+ "failed to find svc "
+ "in upcall string '%s'\n", lbuf);
+ goto out;
+ }
+
/* read supported encryption types if supplied */
if ((p = strstr(lbuf, "enctypes=")) != NULL) {
enctypes = malloc(lbuflen);
@@ -1353,7 +1371,8 @@ handle_gssd_upcall(struct clnt_info *clp)
}
if (strcmp(mech, "krb5") == 0 && clp->servername)
- process_krb5_upcall(clp, uid, clp->gssd_fd, target, service);
+ process_krb5_upcall(clp, uid, clp->gssd_fd, target, service,
+ svc);
else {
if (clp->servername)
printerr(0, "WARNING: handle_gssd_upcall: "