+static int pf_service(int ptoken, char ***rvalues) {
+ parm_1string(rvalues,service); return 0;
+}
+
+static int pf_callinguser(int ptoken, char ***rvalues) {
+ return parm_usernameuid(rvalues,logname,request_mbuf.callinguid);
+}
+
+static int pf_serviceuser(int ptoken, char ***rvalues) {
+ return parm_usernameuid(rvalues,serviceuser,serviceuser_uid);
+}
+
+static int pf_callinggroup(int ptoken, char ***rvalues) {
+ return parm_groups(rvalues,request_mbuf.ngids,calling_gids,calling_groups);
+}
+
+static int pf_servicegroup(int ptoken, char ***rvalues) {
+ return parm_groups(rvalues,service_ngids,service_gids,service_groups);
+}
+
+static int pf_callingusershell(int ptoken, char ***rvalues) {
+ parm_1string(rvalues,callinguser_shell); return 0;
+}
+
+static int pf_serviceusershell(int ptoken, char ***rvalues) {
+ parm_1string(rvalues,serviceuser_shell); return 0;
+}
+
+static int pa_parameter(char ***rvalues, char **rname) {
+ /* Scans a single parameter token and calls the appropriate parameter
+ * function, returning tokv_error (leaving the parser state wherever),
+ * or 0 on success (having just parsed the parameter name).
+ * If rname is non-null then the name of the parameter (malloc'd) will
+ * be stored in it.
+ *
+ * Caller must free *rvalues using freecharparray.
+ */
+ int token, r, i;
+ char *name;
+
+ token= yylex(); if (token == tokv_error) return token;
+ name= xstrsave(yytext);
+ if ((token & tokm_repres) != tokr_nonstring &&
+ !memcmp(yytext,"u-",2) && strlen(yytext)>=3) {
+ for (i=0;
+ i<request_mbuf.nvars && strcmp(yytext+2,defvararray[i].key);
+ i++);
+ if (i>=request_mbuf.nvars) {
+ *rvalues= xmalloc(sizeof(char*));
+ **rvalues= 0;
+ } else {
+ parm_1string(rvalues,defvararray[i].value);
+ }
+ } else if (token & tokt_parameter) {
+ r= (lr_parameter)(token,rvalues);
+ if (r) { free(name); return r; }
+ } else {
+ free(name);
+ return unexpected(token,-1,"parameter name");