The patch permits the file server to force a domain to be used in the p9any negotiation. The dom is specified in fss->attr. If dom is not specified, factotum will work as it currently does. For example, in a file server's Srv .auth function: ... snprint(aux, 128, "proto=p9any dom=%s role=server", dom); srv->keyspec = estrdup9p(aux); ... key = srv->keyspec; keylen = strlen(key); if(auth_rpc(af->rpc, "start", key, keylen) != ARok) goto fail; af->uid = estrdup9p(r->ifcall.uname); ... P9any currently negotiates the proto@dom sending all the p9sk* keys (that can be used as a server) stored in the Server's factotum ring. Client's factotum selects one of them, and then the p9sk1 protocol starts. That scheme works well with stand alone file servers. The problem arises when terminals run file servers that needs authentication. The user's secstore can contain several p9sk* keys, but some of them can be inappropriate to authenticate the session. This problem cannot be solved using the 'role' attribute, because different file systems running in this terminal would need to be authenticated through different auth servers (and the user would need to use these keys to access other file servers as client). Notes: Tue Dec 13 13:57:36 EST 2005 rsc Your example was already supposed to work. I think the problem was a bug in util.c's setattrs, which I have fixed. Please let me know if that doesn't make factotum work properly for you. Reference: /n/sources/patch/sorry/factotum_p9any_force_dom Date: Mon Dec 12 21:33:25 CET 2005 Reviewed-by: rsc --- /sys/src/cmd/auth/factotum/p9any.c Mon Dec 12 21:33:16 2005 +++ /sys/src/cmd/auth/factotum/p9any.c Mon Dec 12 21:33:13 2005 @@ -147,6 +147,7 @@ Keyinfo ki; String *negstr; State *s; + char *dom; s = fss->ps; switch(fss->phase){ @@ -154,6 +155,7 @@ return phaseerror(fss, "read"); case SHaveProtos: + dom = _strfindattr(fss->attr, "dom"); m = 0; negstr = s_new(); mkkeyinfo(&ki, fss, nil); @@ -161,7 +163,10 @@ ki.noconf = 1; ki.user = nil; for(i=0; iattr), "proto=%q dom?", negotiable[i]->name); + if(dom) + anew = setattr(_copyattr(fss->attr), "proto=%q", negotiable[i]->name); + else + anew = setattr(_copyattr(fss->attr), "proto=%q dom?", negotiable[i]->name); ki.attr = anew; for(ki.skip=0; findkey(&k, &ki, nil)==RpcOk; ki.skip++){ if(m++)