rx_SetMaxProcs(tservice, 4);
rx_SetStackSize(tservice, BOZO_LWP_STACKSIZE); /* so gethostbyname works (in cell stuff) */
if (rxkadDisableDotCheck) {
- rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS,
- (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
+ code = rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS,
+ (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
+ if (code) {
+ bozo_Log("Failed to allow dotted principals: code %d\n", code);
+ exit(1);
+ }
}
tservice =
rx_SetMinProcs(tservice, 2);
rx_SetMaxProcs(tservice, lwps);
if (rxkadDisableDotCheck) {
- rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS,
- (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
+ code = rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS,
+ (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
+ if (code) {
+ afs_com_err(whoami, code, "Failed to allow dotted principals");
+ PT_EXIT(3);
+ }
}
tservice =
static void rxi_ScheduleGrowMTUEvent(struct rx_call *call, int secs);
static void rxi_KeepAliveOn(struct rx_call *call);
static void rxi_GrowMTUOn(struct rx_call *call);
-static void rxi_ChallengeOn(struct rx_connection *conn);
+static int rxi_ChallengeOn(struct rx_connection *conn);
static int rxi_CheckCall(struct rx_call *call, int haveCTLock);
static void rxi_AckAllInTransmitQueue(struct rx_call *call);
static void rxi_CancelKeepAliveEvent(struct rx_call *call);
{
int hashindex, i;
struct rx_connection *conn;
+ int code;
SPLVAR;
conn->lastBusy[i] = 0;
}
- RXS_NewConnection(securityObject, conn);
+ code = RXS_NewConnection(securityObject, conn);
hashindex =
CONN_HASH(shost, sport, conn->cid, conn->epoch, RX_CLIENT_CONNECTION);
rx_atomic_inc(&rx_stats.nClientConns);
MUTEX_EXIT(&rx_connHashTable_lock);
USERPRI;
+ if (code) {
+ rxi_ConnectionError(conn, code);
+ }
return conn;
}
void *value)
{
int i;
+ int code;
for (i = 0; i<service->nSecurityObjects; i++) {
if (service->securityObjects[i]) {
- RXS_SetConfiguration(service->securityObjects[i], NULL, type,
- value, NULL);
+ code = RXS_SetConfiguration(service->securityObjects[i], NULL, type,
+ value, NULL);
+ if (code) {
+ return code;
+ }
}
}
return 0;
int *unknownService)
{
int hashindex, flag, i;
+ int code = 0;
struct rx_connection *conn;
*unknownService = 0;
hashindex = CONN_HASH(host, port, cid, epoch, type);
conn->rwind[i] = rx_initReceiveWindow;
}
/* Notify security object of the new connection */
- RXS_NewConnection(conn->securityObject, conn);
+ code = RXS_NewConnection(conn->securityObject, conn);
/* XXXX Connection timeout? */
if (service->newConnProc)
(*service->newConnProc) (conn);
rxLastConn = conn; /* store this connection as the last conn used */
MUTEX_EXIT(&rx_connHashTable_lock);
+ if (code) {
+ rxi_ConnectionError(conn, code);
+ }
return conn;
}
static void
TryAttach(struct rx_call *acall, osi_socket socket,
int *tnop, struct rx_call **newcallp,
- int reachOverride)
+ int reachOverride, int istack)
{
struct rx_connection *conn = acall->conn;
* may not any proc available
*/
} else {
- rxi_ChallengeOn(acall->conn);
+ int code;
+ code = rxi_ChallengeOn(acall->conn);
+ if (code) {
+ /*
+ * Ideally we would rxi_ConnectionError here, but doing that is
+ * difficult, because some callers may have locked 'call',
+ * _and_ another call on the same conn. So we cannot
+ * rxi_ConnectionError, since that needs to lock every call on
+ * the conn. But we can at least abort the call we have.
+ */
+ rxi_CallError(acall, code);
+ rxi_SendCallAbort(acall, NULL, istack, 0);
+ }
}
}
}
* server thread is available, this thread becomes a server
* thread and the server thread becomes a listener thread. */
if (isFirst) {
- TryAttach(call, socket, tnop, newcallp, 0);
+ TryAttach(call, socket, tnop, newcallp, 0, istack);
}
}
/* This is not the expected next packet. */
}
static void
-rxi_UpdatePeerReach(struct rx_connection *conn, struct rx_call *acall)
+rxi_UpdatePeerReach(struct rx_connection *conn, struct rx_call *acall,
+ int istack)
{
struct rx_peer *peer = conn->peer;
if (call != acall)
MUTEX_ENTER(&call->lock);
/* tnop can be null if newcallp is null */
- TryAttach(call, (osi_socket) - 1, NULL, NULL, 1);
+ TryAttach(call, (osi_socket) - 1, NULL, NULL, 1, istack);
if (call != acall)
MUTEX_EXIT(&call->lock);
}
}
if (ap->reason == RX_ACK_PING_RESPONSE)
- rxi_UpdatePeerReach(conn, call);
+ rxi_UpdatePeerReach(conn, call, istack);
if (conn->lastPacketSizeSeq) {
MUTEX_ENTER(&conn->conn_data_lock);
* some calls went into attach-wait while we were waiting
* for authentication..
*/
- rxi_UpdatePeerReach(conn, NULL);
+ rxi_UpdatePeerReach(conn, NULL, istack);
}
return np;
}
rxi_Send(struct rx_call *call, struct rx_packet *p,
int istack)
{
+ int code;
struct rx_connection *conn = call->conn;
/* Stamp each packet with the user supplied status */
/* Allow the security object controlling this call's security to
* make any last-minute changes to the packet */
- RXS_SendPacket(conn->securityObject, call, p);
+ code = RXS_SendPacket(conn->securityObject, call, p);
+ if (code) {
+ MUTEX_EXIT(&call->lock);
+ CALL_HOLD(call, RX_CALL_REFCOUNT_SEND);
+ rxi_ConnectionError(conn, code);
+ CALL_RELE(call, RX_CALL_REFCOUNT_SEND);
+ MUTEX_ENTER(&call->lock);
+ return;
+ }
/* Since we're about to send SOME sort of packet to the peer, it's
* safe to nuke any scheduled end-of-packets ack */
packet = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL);
if (packet) {
- /* If there's no packet available, do this later. */
- RXS_GetChallenge(conn->securityObject, conn, packet);
- rxi_SendSpecial((struct rx_call *)0, conn, packet,
- RX_PACKET_TYPE_CHALLENGE, NULL, -1, 0);
+ int code;
+ code = RXS_GetChallenge(conn->securityObject, conn, packet);
+ if (code && event_raised) {
+ /*
+ * We can only rxi_ConnectionError the connection if we are
+ * running as an event. Otherwise, the caller may have our call
+ * locked, and so we cannot call rxi_ConnectionError (since it
+ * tries to lock each call in the conn).
+ */
+ rxi_FreePacket(packet);
+ rxi_ConnectionError(conn, code);
+ goto done;
+ }
+ if (code == 0) {
+ /* Only send a challenge packet if we were able to allocate a
+ * packet, and the security layer successfully populated the
+ * challenge. */
+ rxi_SendSpecial((struct rx_call *)0, conn, packet,
+ RX_PACKET_TYPE_CHALLENGE, NULL, -1, 0);
+ conn->securityChallengeSent = 1;
+ }
rxi_FreePacket(packet);
- conn->securityChallengeSent = 1;
}
clock_GetTime(&now);
when = now;
* the call times out, or an invalid response is returned. The
* security object associated with the connection is asked to create
* the challenge at this time. */
-static void
+static int
rxi_ChallengeOn(struct rx_connection *conn)
{
int start = 0;
start = 1;
MUTEX_EXIT(&conn->conn_data_lock);
if (start) {
- RXS_CreateChallenge(conn->securityObject, conn);
+ int code;
+ code = RXS_CreateChallenge(conn->securityObject, conn);
+ if (code) {
+ return code;
+ }
rxi_ChallengeEvent(NULL, conn, 0, RX_CHALLENGE_MAXTRIES);
- };
+ }
+ return 0;
}
int (*op_CheckPacket) (struct rx_securityClass * aobj,
struct rx_call * acall,
struct rx_packet * apacket);
- int (*op_DestroyConnection) (struct rx_securityClass * aobj,
- struct rx_connection * aconn);
+ void (*op_DestroyConnection) (struct rx_securityClass * aobj,
+ struct rx_connection * aconn);
int (*op_GetStats) (struct rx_securityClass * aobj,
struct rx_connection * aconn,
struct rx_securityObjectStats * astats);
};
#define RXS_OP(obj,op,args) ((obj && (obj->ops->op_ ## op)) ? (*(obj)->ops->op_ ## op)args : 0)
+#define RXS_OP_VOID(obj,op,args) do { \
+ if (obj && (obj->ops->op_ ## op)) \
+ (*(obj)->ops->op_ ## op)args; \
+} while (0)
#define RXS_Close(obj) RXS_OP(obj,Close,(obj))
#define RXS_NewConnection(obj,conn) RXS_OP(obj,NewConnection,(obj,conn))
#define RXS_GetResponse(obj,conn,packet) RXS_OP(obj,GetResponse,(obj,conn,packet))
#define RXS_CheckResponse(obj,conn,packet) RXS_OP(obj,CheckResponse,(obj,conn,packet))
#define RXS_CheckPacket(obj,call,packet) RXS_OP(obj,CheckPacket,(obj,call,packet))
-#define RXS_DestroyConnection(obj,conn) RXS_OP(obj,DestroyConnection,(obj,conn))
+#define RXS_DestroyConnection(obj,conn) RXS_OP_VOID(obj,DestroyConnection,(obj,conn))
#define RXS_GetStats(obj,conn,stats) RXS_OP(obj,GetStats,(obj,conn,stats))
#define RXS_SetConfiguration(obj, conn, type, value, currentValue) RXS_OP(obj, SetConfiguration,(obj,conn,type,value,currentValue))
for (tc = rx_connHashTable[i]; tc; tc = tc->next) {
if ((all || rxi_IsConnInteresting(tc))
&& tin.index-- <= 0) {
+ int do_secstats = 0;
tconn.host = tc->peer->host;
tconn.port = tc->peer->port;
tconn.cid = htonl(tc->cid);
tconn.type = tc->type;
tconn.securityIndex = tc->securityIndex;
if (tc->securityObject) {
- RXS_GetStats(tc->securityObject, tc,
- &tconn.secStats);
+ int code;
+ code = RXS_GetStats(tc->securityObject, tc,
+ &tconn.secStats);
+ if (code == 0) {
+ do_secstats = 1;
+ }
+ }
+ if (do_secstats) {
#define DOHTONL(a) (tconn.secStats.a = htonl(tconn.secStats.a))
#define DOHTONS(a) (tconn.secStats.a = htons(tconn.secStats.a))
DOHTONL(flags);
sizeof(tconn.secStats.sparel) /
sizeof(afs_int32); i++)
DOHTONL(sparel[i]);
+ } else {
+ memset(&tconn.secStats, 0, sizeof(tconn.secStats));
}
MUTEX_EXIT(&rx_connHashTable_lock);
static int rxgk_ClientCheckPacket(struct rx_securityClass *aobj,
struct rx_call *acall,
struct rx_packet *apacket);
-static int rxgk_DestroyClientConnection(struct rx_securityClass *aobj,
- struct rx_connection *aconn);
+static void rxgk_DestroyClientConnection(struct rx_securityClass *aobj,
+ struct rx_connection *aconn);
static int rxgk_ClientGetStats(struct rx_securityClass *aobj,
struct rx_connection *aconn,
struct rx_securityObjectStats *astats);
return RXGK_INCONSISTENCY;
}
-static int
+static void
rxgk_DestroyClientConnection(struct rx_securityClass *aobj,
struct rx_connection *aconn)
{
- return RXGK_INCONSISTENCY;
}
static int
struct rx_packet *apacket);
static int rxgk_ServerCheckPacket(struct rx_securityClass *aobj,
struct rx_call *acall, struct rx_packet *apacket);
-static int rxgk_DestroyServerConnection(struct rx_securityClass *aobj,
- struct rx_connection *aconn);
+static void rxgk_DestroyServerConnection(struct rx_securityClass *aobj,
+ struct rx_connection *aconn);
static int rxgk_ServerGetStats(struct rx_securityClass *aobj,
struct rx_connection *aconn,
struct rx_securityObjectStats *astats);
return RXGK_INCONSISTENCY;
}
-static int
+static void
rxgk_DestroyServerConnection(struct rx_securityClass *aobj,
struct rx_connection *aconn)
{
- return RXGK_INCONSISTENCY;
}
static int
/* either: called to destroy a connection. */
-int
+void
rxkad_DestroyConnection(struct rx_securityClass *aobj,
struct rx_connection *aconn)
{
cconn = rx_GetSecurityData(aconn);
tcp = (struct rxkad_cprivate *)aobj->privateData;
if (!(tcp->type & rxkad_client))
- return RXKADINCONSISTENCY;
+ return; /* something is weird; bail out */
if (cconn) {
rx_SetSecurityData(aconn, NULL);
rxi_Free(cconn, sizeof(struct rxkad_cconn));
}
aobj->refCount--; /* decrement connection counter */
if (aobj->refCount <= 0) {
- afs_int32 code;
- code = FreeObject(aobj);
- if (code)
- return code;
+ (void)FreeObject(aobj);
}
- return 0;
}
/* either: decode packet */
extern int rxkad_Close(struct rx_securityClass *aobj);
extern int rxkad_NewConnection(struct rx_securityClass *aobj,
struct rx_connection *aconn);
-extern int rxkad_DestroyConnection(struct rx_securityClass *aobj,
- struct rx_connection *aconn);
+extern void rxkad_DestroyConnection(struct rx_securityClass *aobj,
+ struct rx_connection *aconn);
extern int rxkad_CheckPacket(struct rx_securityClass *aobj,
struct rx_call *acall,
struct rx_packet *apacket);
exit(-1);
}
if (rxkadDisableDotCheck) {
- rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS,
- (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
+ code = rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS,
+ (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
+ if (code) {
+ ViceLog(0, ("Failed to allow dotted principals: code %d\n", code));
+ exit(-1);
+ }
}
rx_SetMinProcs(tservice, 3);
rx_SetMaxProcs(tservice, lwps);
rx_SetMaxProcs(tservice, lwps);
if (rxkadDisableDotCheck) {
- rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS,
- (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
+ code = rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS,
+ (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
+ if (code) {
+ VLog(0, ("vlserver: failed to allow dotted principals: %s\n",
+ afs_error_message(code)));
+ exit(2);
+ }
}
tservice =
#endif
if (rxkadDisableDotCheck) {
- rx_SetSecurityConfiguration(service, RXS_CONFIG_FLAGS,
- (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
+ code = rx_SetSecurityConfiguration(service, RXS_CONFIG_FLAGS,
+ (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
+ if (code) {
+ fprintf(stderr,
+ "volser: failed to allow dotted principals: code %d\n",
+ code);
+ VS_EXIT(1);
+ }
}
service =