[OpenAFS] Any way to create srvtabs for use with kaserver...

Marcus Watts mdw@umich.edu
Wed, 06 Mar 2002 23:10:27 -0500


Eric Knudstrup <eric@knudstrup.org> writes:

> Thanks for the reply about the library ordering.  I was coding a few hours after
> I should have been sleeping.
> Ok, I have something mocked up for the principal creation routine, but I keep
> getting an error message:
> 
> ./afssvcnew httpd temp.srvtab
> Password:test
> Failed to create principal: RPC interface mismatch (-450)
... (most of source deleted) ...
> 
> 		printf("%p\n", key);
> 		code = ubik_Call (KAM_CreateUser, conn, 0, argv[1], NULL, key);
> 		if(code) {
> 				fprintf(stderr, "Failed to create principal: %s\n", error_message(code));

The source doesn't quite correspond to your claimed error.
If the source is to be believed, it should have printed out
some pointer, a newline, and then the error message.

In any event, -450 is a client marshal error.  Here's a copy of
"negative_message", which you (or someone) might want to compare
with & merge into comerr/error_msg.c in openafs:
	static char *negative_message(code)
	int code; {
	    if (code == -1)	/* RX_CALL_DEAD */
		return "server or network not responding";
	    else if (code == -2)	/* RX_INVALID_OPERATION */
		return "invalid RPC (RX) operation";
	    else if (code == -3)	/* RX_CALL_TIMEOUT */
		return "server not responding promptly";
	#if 0	/* can't happen */
	    else if (code == -4)	/* RX_EOF */
		return "RPC (RX) end of file";
	#endif
	    else if (code == -5)	/* RX_PROTOCOL_ERROR rw order violation */
		return "RPC (RX) protocol error";
	    else if (code == -6)	/* RX_USER_ABORT (multi_Finalize) */
		return "RPC (RX) abort";
	    else if (code == -7)	/* RX_ADDRINUSE (rx_Init) */
		return "port address already in use";
	#if 0	/* can't happen */
	    else if (code == -8)	/* RX_MSGSIZE */
		return "packet too big; must fragment";
	#endif
	    else if (code <= -450 && code > -500) {
		sprintf(buffer, "RPC interface mismatch (%d)", code);
		switch(code)
		{
		case -450:	strcat(buffer, " client marshal"); break;
		case -451:	strcat(buffer, " client un-marshal"); break;
		case -452:	strcat(buffer, " server marshal"); break;
		case -453:	strcat(buffer, " server un-marshal"); break;
		case -454:	strcat(buffer, " decode"); break;
		case -455:	strcat(buffer, " opcode"); break;
		case -456:	strcat(buffer, " server free"); break;
		case -457:	strcat(buffer, " client free"); break;
		}
		return buffer;
	    }
	    else {
		sprintf(buffer, "unknown RPC error (%d)", code);
		return buffer;
	    }
	}
The switch table here is the important thing; it will print
out more useful information about those annoying -450 class error
messages.

Now, getting back to your problem.  You say you got a -450 return,
which is a client marshal error.  That means an xdr error while taking
your procedure arguments and packing them into a byte stream for
the wire protocol.  Here's what you had:
> 		code = ubik_Call (KAM_CreateUser, conn, 0, argv[1], NULL, key);
Here's what your parameters are:
	KAM_CreateUser		- pointer to function
	conn			- ubik connection
	0			- int aflags (not actually used)
	argv[1]			- char *name, parameter to KAM_CreateUser
	NULL			- char *instance, parameter to KAM_CreateUser
	key			- struct EncryptionKey {char key[8];} key;
the name & instance are packed onto the wire using "xdr_string".
xdr_string does a strlen on the passed in string, sends the
resulting int out on the wire, checks to see that the int
isn't too big, then sends the string contents as packed bytes,
followed by 0-3 bytes of null padding.

Since you're passing a NULL for the instance, that NULL will first be
seen by xdr_string.  On some machines, that will core dump, but since
you got back -450, you must be using some machine that either has more
than 64 bytes of valid non-zero memory at 0, or that has an xdr_string
that checks for a passed in NULL and fails more "nicely" if so.  In any
case, you want to pass in an empty string, "" instead of NULL.

				-Marcus Watts
				UM ITCS Umich Systems Group