want a remote kill command.
/*
- * $Id: auth.c,v 1.44.2.3.2.14 2004-06-18 07:58:20 bfernhomberg Exp $
+ * $Id: auth.c,v 1.44.2.3.2.15 2004-07-01 01:27:34 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
*/
switch (type) {
case 0: /* old version ?*/
+ tklen = obj->sinfo.sessiontoken_len;
+ token = obj->sinfo.sessiontoken;
break;
case 1: /* disconnect */
case 2: /* reconnect update id */
*rbuflen = 0;
ibuf += 2;
+#if 0
/* check for guest user */
if ( 0 == (strcasecmp(obj->username, obj->options.guest)) ) {
return AFPERR_MISC;
}
+#endif
memcpy(&type, ibuf, sizeof(type));
type = ntohs(type);
extern void server_child_free __P((server_child *));
extern void server_child_kill __P((server_child *, const int, const int));
-extern void server_child_kill_one __P((server_child *children, const int forkid, const pid_t pid));
-extern void server_child_kill_one_by_id __P((server_child *children, const int forkid, const pid_t pid,
+extern void server_child_kill_one __P((server_child *children, const int forkid, const pid_t, const uid_t));
+extern void server_child_kill_one_by_id __P((server_child *children, const int forkid, const pid_t pid, const uid_t,
const u_int32_t len, char *id, u_int32_t boottime));
extern void server_child_setup __P((server_child *, const int, void (*)()));
/*
- * $Id: server_child.c,v 1.7.4.1.2.3 2004-02-16 08:59:52 didg Exp $
+ * $Id: server_child.c,v 1.7.4.1.2.4 2004-07-01 01:27:34 didg Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
#define HASH(i) ((((i) >> 8) ^ (i)) & (CHILD_HASHSIZE - 1))
struct server_child_data {
- pid_t pid;
- u_int32_t time;
+ pid_t pid;
+ uid_t uid;
+ int valid;
+ u_int32_t time;
u_int32_t idlen;
char *clientid;
}
child->pid = pid;
+ child->valid = 0;
hash_child(fork->table, child);
children->count++;
sigprocmask(SIG_SETMASK, &oldsig, NULL);
* a plain-old linked list
* FIXME use resolve_child ?
*/
-void server_child_kill_one(server_child *children, const int forkid, const pid_t pid)
+void server_child_kill_one(server_child *children, const int forkid, const pid_t pid, const uid_t uid)
{
server_child_fork *fork;
struct server_child_data *child, *tmp;
while (child) {
tmp = child->next;
if (child->pid == pid) {
- kill(child->pid, SIGTERM);
+ if (!child->valid) {
+ /* hmm, client 'guess' the pid, rogue? */
+ LOG(log_info, logtype_default, "Disconnecting old session (%d) no token, bailout!", child->pid);
+ }
+ else if (child->uid != uid) {
+ LOG(log_info, logtype_default, "Disconnecting old session (%d) not the same user, bailout!", child->pid);
+ }
+ else {
+ kill(child->pid, SIGTERM);
+ }
}
child = tmp;
}
/* see if there is a process for the same mac */
/* if the times don't match mac has been rebooted */
-void server_child_kill_one_by_id(server_child *children, const int forkid, const pid_t pid,
+void server_child_kill_one_by_id(server_child *children, const int forkid, const pid_t pid,
+ const uid_t uid,
const u_int32_t idlen, char *id, u_int32_t boottime)
{
server_child_fork *fork;
if ( child->pid != pid) {
if ( child->idlen == idlen && !memcmp(child->clientid, id, idlen)) {
if ( child->time != boottime ) {
- kill(child->pid, SIGTERM);
- LOG(log_info, logtype_default, "Disconnecting old session %d, client rebooted.", child->pid);
+ if (uid == child->uid) {
+ kill(child->pid, SIGTERM);
+ LOG(log_info, logtype_default, "Disconnecting old session %d, client rebooted.", child->pid);
+ }
+ else {
+ LOG(log_info, logtype_default, "Disconnecting old session not the same uid, bailout!");
+ }
}
else {
LOG(log_info, logtype_default,
if (child->clientid) {
free(child->clientid);
}
+ child->uid = uid;
+ child->valid = 1;
child->idlen = idlen;
child->clientid = id;
LOG(log_info, logtype_default, "Setting clientid (len %d) for %d, boottime %X", idlen, child->pid, boottime);
/*
- * $Id: server_ipc.c,v 1.1.4.1.2.1 2004-01-10 08:29:16 bfernhomberg Exp $
+ * $Id: server_ipc.c,v 1.1.4.1.2.2 2004-07-01 01:27:34 didg Exp $
*
* All rights reserved. See COPYRIGHT.
*
typedef struct ipc_header {
u_int16_t command;
pid_t child_pid;
+ uid_t uid;
u_int32_t len;
char *msg;
} ipc_header;
/* assume signals SA_RESTART set */
memcpy (&pid, ipc->msg, sizeof(pid_t));
- LOG(log_info, logtype_default, "child %d disconnected", pid);
- server_child_kill_one(children, CHILD_DSIFORK, pid);
+ LOG(log_info, logtype_default, "child %d user %d disconnected", pid, ipc->uid);
+ server_child_kill_one(children, CHILD_DSIFORK, pid, ipc->uid);
return 0;
}
}
memcpy (clientid, p, idlen);
- server_child_kill_one_by_id (children, CHILD_DSIFORK, ipc->child_pid, idlen, clientid, boottime);
+ server_child_kill_one_by_id (children, CHILD_DSIFORK, ipc->child_pid, ipc->uid, idlen, clientid, boottime);
/* FIXME byte to ascii if we want to log clientid */
LOG (log_info, logtype_afpd, "ipc_get_session: len: %u, idlen %d, time %x", ipc->len, idlen, boottime);
return 0;
}
-#define IPC_HEADERLEN 10
+#define IPC_HEADERLEN 14
#define IPC_MAXMSGSIZE 90
-/* ----------------- */
+/* -----------------
+ * Ipc format
+ * command
+ * pid
+ * uid
+ *
+*/
int server_ipc_read(server_child *children)
{
int ret = 0;
}
p = buf;
+
memcpy(&ipc.command, p, sizeof(ipc.command));
p += sizeof(ipc.command);
+
memcpy(&ipc.child_pid, p, sizeof(ipc.child_pid));
p += sizeof(ipc.child_pid);
+
+ memcpy(&ipc.uid, p, sizeof(ipc.uid));
+ p += sizeof(ipc.uid);
+
memcpy(&ipc.len, p, sizeof(ipc.len));
/* This should never happen */
{
char block[IPC_MAXMSGSIZE], *p;
pid_t pid;
+ uid_t uid;
p = block;
memset ( p, 0 , IPC_MAXMSGSIZE);
pid = getpid();
memcpy(p, &pid, sizeof(pid_t));
p += sizeof(pid_t);
+
+ /* FIXME
+ * using uid is wrong. It will not disconnect if the new connection
+ * is with a different user.
+ * But we really don't want a remote kill command.
+ */
+ uid = geteuid();
+ memcpy(p, &uid, sizeof(uid_t));
+ p += sizeof(uid_t);
memcpy(p, &len, 4);
p += 4;