Initial
This commit is contained in:
commit
d2f0741fd4
38
Makefile
Normal file
38
Makefile
Normal file
@ -0,0 +1,38 @@
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -c -o
|
||||
LDFLAGS = -Wall -lcrypt -o
|
||||
EXE = userv
|
||||
RM = rm -f
|
||||
|
||||
OBJECTS = main.o data.o networking.o misc.o common.o logging.o signal.o context.o
|
||||
|
||||
all: $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) $(EXE) $(OBJECTS)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJECTS) $(EXE)
|
||||
|
||||
main.o: main.c
|
||||
$(CC) $(CFLAGS) main.o main.c
|
||||
|
||||
data.o: data.c
|
||||
$(CC) $(CFLAGS) data.o data.c
|
||||
|
||||
networking.o: networking.c
|
||||
$(CC) $(CFLAGS) networking.o networking.c
|
||||
|
||||
misc.o: misc.c
|
||||
$(CC) $(CFLAGS) misc.o misc.c
|
||||
|
||||
common.o: common.c
|
||||
$(CC) $(CFLAGS) common.o common.c
|
||||
|
||||
logging.o: logging.c
|
||||
$(CC) $(CFLAGS) logging.o logging.c
|
||||
|
||||
signal.o: signal.c
|
||||
$(CC) $(CFLAGS) signal.o signal.c
|
||||
|
||||
context.o: context.c
|
||||
$(CC) $(CFLAGS) context.o context.c
|
||||
|
77
PROTO
Normal file
77
PROTO
Normal file
@ -0,0 +1,77 @@
|
||||
Lines beginning with "S:" are server messages.
|
||||
Lines beginning with "C:" are client messages.
|
||||
|
||||
S: <listening on port 8778>
|
||||
C: <connecting>
|
||||
If the client is from an allowed IP:
|
||||
S: R
|
||||
Or else:
|
||||
S: D
|
||||
S: <close connection>
|
||||
|
||||
From now on, we assume that a connection is already built to the server
|
||||
|
||||
C: L <uname> <pass>
|
||||
If the client is already logged in:
|
||||
S: L
|
||||
If uname or pass is missing:
|
||||
S: E
|
||||
If the specified user is not allowed to login:
|
||||
S: D
|
||||
If the specified uname/pass combination is bad:
|
||||
S: B
|
||||
If login successful:
|
||||
S: S
|
||||
|
||||
C: Q
|
||||
S: S
|
||||
S: <close connection>
|
||||
|
||||
C: U <uid>
|
||||
If client hasn't login yet:
|
||||
S: L
|
||||
If uid is not numeric:
|
||||
S: E
|
||||
If uid is used:
|
||||
S: U
|
||||
If uid is free:
|
||||
S:F
|
||||
|
||||
C: N <uname>
|
||||
If client hasn't login yet:
|
||||
S: L
|
||||
If uname exists:
|
||||
S: U
|
||||
If uname doesn't exist:
|
||||
S: F
|
||||
|
||||
C: A <uname>:<uid>:<teacher?>:<samba?>:<passwd>:<comment>
|
||||
If client hasn't login yet:
|
||||
S: L
|
||||
If uid, teacher?, samba?, passwd or comment is not specified
|
||||
S: E
|
||||
If uid is not numeric:
|
||||
S: E
|
||||
If uid or uname is used:
|
||||
S: E
|
||||
If teacher? not 0 nor 1, and samba? not 0 nor 1
|
||||
S: E
|
||||
If tempfile or scriptfile couldn't be created:
|
||||
S: F
|
||||
If user couldn't be created:
|
||||
S: F
|
||||
If user has been created:
|
||||
S: S
|
||||
|
||||
C: D <uname>
|
||||
If client hasn't login yet:
|
||||
S: L
|
||||
If uname doesn't exist:
|
||||
S: E
|
||||
If scriptfile couldn't be created:
|
||||
S: F
|
||||
If user cannot be deleted:
|
||||
S: F
|
||||
If user is deleted:
|
||||
S: S
|
||||
|
5
README
Normal file
5
README
Normal file
@ -0,0 +1,5 @@
|
||||
This project is a high-school attempt to create centralized user
|
||||
management, long before I heard about LDAP and the likes.
|
||||
|
||||
I release this as a public domain, I guess you can learn this-and-that
|
||||
from it.
|
189
common.c
Normal file
189
common.c
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* UserServer/0.1
|
||||
* common.c - Common functions
|
||||
*
|
||||
* Copyright (C) 2002 Gergely Polonkai
|
||||
* Copyright (C) 2002-2006 P-Team Programmers' Group
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have recieved a copy of the GNU General Public License
|
||||
* along with this program; if not, write to Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA, 02111-1307, USA.
|
||||
*
|
||||
* GNU GPL is in doc/COPYING
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <crypt.h>
|
||||
|
||||
#include "userv.h"
|
||||
#include "functions.h"
|
||||
|
||||
char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
int
|
||||
ParseConfig(void) {
|
||||
FILE *cf;
|
||||
char buf[1024];
|
||||
char *line;
|
||||
int nl = 0;
|
||||
|
||||
if ((cf = fopen("/etc/userv.conf", "r")) == NULL)
|
||||
return ERR_NOCF;
|
||||
|
||||
memset(&buf, 0, 1024);
|
||||
while (fgets((char *)&buf, 1023, cf)) {
|
||||
char *param;
|
||||
int i;
|
||||
|
||||
nl++;
|
||||
if ((line = trim(buf, NULL))) {
|
||||
if (strncmp(line, "listen ", 7) == 0) {
|
||||
param = strchr(line, ' ') + 1;
|
||||
for (i = 0; i < strlen(param); i++)
|
||||
if (isspace(*(param + i))) {
|
||||
*(param + i) = 0;
|
||||
break;
|
||||
}
|
||||
if (!valid_ip(param))
|
||||
return nl;
|
||||
if (AddListen(param) != ERR_OK)
|
||||
return ERR_NOMEM;
|
||||
}
|
||||
if (strncmp(line, "confserv ", 9) == 0) {
|
||||
param = strchr(line, ' ') + 1;
|
||||
for (i = 0; i < strlen(param); i++)
|
||||
if (isspace(*(param + 1))) {
|
||||
*(param + i) = 0;
|
||||
break;
|
||||
}
|
||||
if (!valid_ip(param))
|
||||
return nl;
|
||||
if (AddConfig(param) != ERR_OK)
|
||||
return ERR_NOMEM;
|
||||
}
|
||||
if (strncmp(line, "server ", 7) == 0) {
|
||||
param = strchr(line, ' ') + 1;
|
||||
for (i = 0; i < strlen(param); i++)
|
||||
if (isspace(*(param + 1))) {
|
||||
*(param + i) = 0;
|
||||
break;
|
||||
}
|
||||
if (!valid_ip(param))
|
||||
return nl;
|
||||
if (AddPeer(param) != ERR_OK)
|
||||
return ERR_NOMEM;
|
||||
}
|
||||
if (strncmp(line, "client ", 7) == 0) {
|
||||
param = strchr(line, ' ') + 1;
|
||||
for (i = 0; i < strlen(param); i++)
|
||||
if (isspace(*(param + i))) {
|
||||
*(param + i) = 0;
|
||||
break;
|
||||
}
|
||||
if (!valid_ip(param))
|
||||
return nl;
|
||||
if (AddClient(param) != ERR_OK)
|
||||
return ERR_NOMEM;
|
||||
}
|
||||
if (strncmp(line, "user ", 5) == 0) {
|
||||
param = strchr(line, ' ') + 1;
|
||||
for (i = 0; i < strlen(param); i++)
|
||||
if (isspace(*(param + i))) {
|
||||
*(param + i) = 0;
|
||||
break;
|
||||
}
|
||||
if (!valid_user(param))
|
||||
return nl;
|
||||
if (AddUser(param) != ERR_OK)
|
||||
return ERR_NOMEM;
|
||||
}
|
||||
free(line);
|
||||
}
|
||||
memset(buf, 0, 1024);
|
||||
}
|
||||
fclose(cf);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
int
|
||||
Is_UID_exist(uid_t uid) {
|
||||
if (getpwuid(uid) == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
pwcheck(char *uname, char *passw) {
|
||||
struct passwd *pwentry;
|
||||
char buf[1024];
|
||||
FILE *fd;
|
||||
char *pwd;
|
||||
|
||||
if ((pwentry = getpwnam(uname)) == NULL)
|
||||
return ERR_NOUSER;
|
||||
|
||||
if (strcmp(pwentry->pw_passwd, "x") == 0) {
|
||||
if ((fd = fopen("/etc/shadow", "r")) == NULL)
|
||||
return ERR_NOSHADOW;
|
||||
|
||||
memset(&buf, 0, 1024);
|
||||
while (fgets((char *)&buf, 1023, fd)) {
|
||||
if (strncmp((char *)&buf, uname, strlen(uname)) == 0)
|
||||
break;
|
||||
memset(&buf, 0, 1024);
|
||||
}
|
||||
fclose(fd);
|
||||
} else
|
||||
strcpy((char *)&buf, pwentry->pw_passwd);
|
||||
|
||||
pwd = strchr((char *)&buf, ':') + 1;
|
||||
if (pwd - 1 == NULL)
|
||||
return ERR_NOPASS;
|
||||
|
||||
*(strchr(pwd, ':')) = 0;
|
||||
|
||||
if (strcmp(crypt(passw, pwd), pwd) == 0)
|
||||
return ERR_OK;
|
||||
|
||||
return ERR_BADPASS;
|
||||
}
|
||||
|
||||
void
|
||||
salt(char *where) {
|
||||
int i;
|
||||
if (!where)
|
||||
return;
|
||||
|
||||
strncpy(where, "$1$", 3);
|
||||
for (i = 3; i < 11; i++)
|
||||
where[i] = table[(int)(1.0 * strlen(table) * rand() / (RAND_MAX + 1.0))];
|
||||
where[11] = '$';
|
||||
where[12] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
tempname(char *where, size_t len) {
|
||||
int i;
|
||||
if (!where)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
where[i] = table[(int)(1.0 * strlen(table) * rand() / (RAND_MAX + 1.0))];
|
||||
where[len] = 0;
|
||||
}
|
||||
|
48
context.c
Normal file
48
context.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* UserServer/0.1
|
||||
* context.c - Context debugging
|
||||
*
|
||||
* Copyright (C) 2002 Gergely Polonkai
|
||||
* Copyright (C) 2002-2006 P-Team Programmers' Group
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have recieved a copy of the GNU General Public License
|
||||
* along with this program; if not, write to Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA, 02111-1307, USA.
|
||||
*
|
||||
* GNU GPL is in doc/COPYING
|
||||
*/
|
||||
|
||||
#include "userv.h"
|
||||
#include "functions.h"
|
||||
|
||||
#ifdef CONTEXT_DEBUG
|
||||
# include <string.h>
|
||||
# include <stdio.h>
|
||||
|
||||
char fn[40] = "";
|
||||
int ln = 0;
|
||||
|
||||
void
|
||||
n_Context(char *fname, int line) {
|
||||
memset(&fn, 0, 40);
|
||||
strncpy((char *)&fn, fname, 39);
|
||||
ln = line;
|
||||
}
|
||||
|
||||
void
|
||||
n_PrintContext(void) {
|
||||
Log(MT_MSG, "Last context was at %s:%d", fn, ln);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
251
data.c
Normal file
251
data.c
Normal file
@ -0,0 +1,251 @@
|
||||
/*
|
||||
* UserServer/0.1
|
||||
* data.c - Handling local data
|
||||
*
|
||||
* Copyright (C) 2002 Gergely Polonkai
|
||||
* Copyright (C) 2002-2006 P-Team Programmers' Group
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have recieved a copy of the GNU General Public License
|
||||
* along with this program; if not, write to Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA, 02111-1307, USA.
|
||||
*
|
||||
* GNU GPL is in doc/COPYING
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "userv.h"
|
||||
#include "functions.h"
|
||||
|
||||
int
|
||||
AddListen(char *IP) {
|
||||
LST *temp;
|
||||
char *ip;
|
||||
|
||||
if ((ip = strdup(IP)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
|
||||
if (laddr) {
|
||||
temp = laddr;
|
||||
while (temp->next)
|
||||
temp = temp->next;
|
||||
if ((temp->next = malloc(LSTS)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
temp->next->next = NULL;
|
||||
temp->next->IP = ip;
|
||||
} else {
|
||||
if ((laddr = malloc(LSTS)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
laddr->next = NULL;
|
||||
laddr->IP = ip;
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
int
|
||||
AddConfig(char *IP) {
|
||||
SST *temp;
|
||||
char *ip;
|
||||
|
||||
if ((ip = strdup(IP)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
|
||||
if (saddr) {
|
||||
temp = saddr;
|
||||
while (temp->next)
|
||||
temp = temp->next;
|
||||
if ((temp->next = malloc(SSTS)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
temp->next->next = NULL;
|
||||
temp->next->IP = ip;
|
||||
} else {
|
||||
if ((saddr = malloc(SSTS)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
saddr->next = NULL;
|
||||
saddr->IP = ip;
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
int
|
||||
AddPeer(char *IP) {
|
||||
PST *temp;
|
||||
char *ip;
|
||||
|
||||
if ((ip = strdup(IP)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
|
||||
if (paddr) {
|
||||
temp = paddr;
|
||||
while (temp->next)
|
||||
temp = temp->next;
|
||||
if ((temp->next = malloc(SSTS)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
temp->next->next = NULL;
|
||||
temp->next->IP = ip;
|
||||
} else {
|
||||
if ((paddr = malloc(SSTS)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
paddr->next = NULL;
|
||||
paddr->IP = ip;
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
int
|
||||
AddClient(char *IP) {
|
||||
CST *temp;
|
||||
char *ip;
|
||||
|
||||
if ((ip = strdup(IP)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
|
||||
if (caddr) {
|
||||
temp = caddr;
|
||||
while (temp->next)
|
||||
temp = temp->next;
|
||||
if ((temp->next = malloc(CSTS)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
temp->next->next = NULL;
|
||||
temp->next->IP = ip;
|
||||
} else {
|
||||
if ((caddr = malloc(CSTS)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
caddr->next = NULL;
|
||||
caddr->IP = ip;
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
int
|
||||
AddUser(char *name) {
|
||||
UST *temp;
|
||||
char *un;
|
||||
|
||||
if ((un = strdup(name)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
|
||||
if (auser) {
|
||||
temp = auser;
|
||||
while (temp->next)
|
||||
temp = temp->next;
|
||||
if ((temp->next = malloc(USTS)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
temp->next->next = NULL;
|
||||
temp->next->uname = un;
|
||||
} else {
|
||||
if ((auser = malloc(USTS)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
auser->next = NULL;
|
||||
auser->uname = un;
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void
|
||||
CleanUp(int type) {
|
||||
if (laddr) {
|
||||
LST *temp;
|
||||
temp = laddr->next;
|
||||
if (laddr->IP)
|
||||
free(laddr->IP);
|
||||
free(laddr);
|
||||
while (temp) {
|
||||
LST *t = temp;
|
||||
temp = temp->next;
|
||||
if (t->IP)
|
||||
free(t->IP);
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
laddr = NULL;
|
||||
|
||||
if (paddr) {
|
||||
PST *temp;
|
||||
temp = paddr->next;
|
||||
if (paddr->IP)
|
||||
free(paddr->IP);
|
||||
free(paddr);
|
||||
while (temp) {
|
||||
PST *t = temp;
|
||||
temp = temp->next;
|
||||
if (t->IP)
|
||||
free(t->IP);
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
paddr = NULL;
|
||||
|
||||
if (saddr) {
|
||||
SST *temp;
|
||||
temp = saddr->next;
|
||||
if (saddr->IP)
|
||||
free(saddr->IP);
|
||||
free(saddr);
|
||||
while (temp) {
|
||||
SST *t = temp;
|
||||
temp = temp->next;
|
||||
if (t->IP)
|
||||
free(t->IP);
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
saddr = NULL;
|
||||
|
||||
if (caddr) {
|
||||
CST *temp;
|
||||
temp = caddr->next;
|
||||
if (caddr->IP)
|
||||
free(caddr->IP);
|
||||
free(caddr);
|
||||
while (temp) {
|
||||
CST *t = temp;
|
||||
temp = temp->next;
|
||||
if (t->IP)
|
||||
free(t->IP);
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
caddr = NULL;
|
||||
|
||||
if (auser) {
|
||||
UST *temp;
|
||||
temp = auser->next;
|
||||
if (auser->uname)
|
||||
free(auser->uname);
|
||||
free(auser);
|
||||
while (temp) {
|
||||
UST *t = temp;
|
||||
temp = temp->next;
|
||||
if (t->uname)
|
||||
free(t->uname);
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
auser = NULL;
|
||||
|
||||
while (nconn) {
|
||||
if ((nconn->sfd != -1) && (type == 0) && (nconn->type == CT_CLIENT))
|
||||
Send(nconn->sfd, "T\n");
|
||||
DelConn(nconn->sfd);
|
||||
}
|
||||
nconn = NULL;
|
||||
}
|
||||
|
35
functions.h
Normal file
35
functions.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef _US_FUNCTIONS_H
|
||||
# define _US_FUNCTIONS_H
|
||||
|
||||
# include <sys/types.h>
|
||||
# include "userv.h"
|
||||
|
||||
int AddListen(char *);
|
||||
int AddClient(char *);
|
||||
int AddUser(char *);
|
||||
int AddConfig(char *);
|
||||
int AddPeer(char *);
|
||||
void CleanUp(int);
|
||||
int StartListening(void);
|
||||
int valid_user(char *);
|
||||
int valid_ip(char *);
|
||||
char *trim(char *, char *);
|
||||
int ip_allowed(char *);
|
||||
int MainLoop(void);
|
||||
int ParseConfig(void);
|
||||
int pwcheck(char *, char *);
|
||||
int IsNum(char *);
|
||||
int Is_UID_exist(uid_t);
|
||||
void salt(char *);
|
||||
void tempname(char *, size_t);
|
||||
int user_allowed(char *);
|
||||
void Log(int, char *, ...);
|
||||
void SetSignals(void);
|
||||
void Send(int, char *, ...);
|
||||
void DelConn(int);
|
||||
# ifdef CONTEXT_DEBUG
|
||||
void n_Context(char *, int);
|
||||
void n_PrintContext(void);
|
||||
# endif
|
||||
|
||||
#endif /* _US_FUNCTIONS_H */
|
63
logging.c
Normal file
63
logging.c
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* UserServer/0.1
|
||||
* logging.c - Logging facility
|
||||
*
|
||||
* Copyright (C) 2002 Gergely Polonkai
|
||||
* Copyright (C) 2002-2006 P-Team Programmers' Group
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have recieved a copy of the GNU General Public License
|
||||
* along with this program; if not, write to Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA, 02111-1307, USA.
|
||||
*
|
||||
* GNU GPL is in doc/COPYING
|
||||
*/
|
||||
|
||||
#include <syslog.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "userv.h"
|
||||
#include "functions.h"
|
||||
|
||||
static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
|
||||
void
|
||||
Log(int type, char *fmt, ...) {
|
||||
char buf1[256];
|
||||
va_list ap;
|
||||
FILE *lf;
|
||||
int prior;
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf1, 255, fmt, ap);
|
||||
va_end(ap);
|
||||
if ((lf = fopen("/var/log/userv.log", "a")) != NULL) {
|
||||
now = time(NULL);
|
||||
tm = localtime((const time_t *)&now);
|
||||
|
||||
fprintf(lf, "%s %2d %02d:%02d:%02d UserServer[%d] %s: %s\n", month[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, getpid(), (type == MT_ERROR) ? "ERR" : "MSG", buf1);
|
||||
|
||||
fclose(lf);
|
||||
}
|
||||
|
||||
openlog("UserServer", LOG_PID, LOG_DAEMON);
|
||||
prior = LOG_DAEMON;
|
||||
prior |= (type == MT_ERROR) ? LOG_ERR : LOG_NOTICE;
|
||||
syslog(prior, "%s: %s", (type == MT_ERROR) ? "ERR" : "MSG", buf1);
|
||||
closelog();
|
||||
}
|
||||
|
116
main.c
Normal file
116
main.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* UserServer/0.1
|
||||
* main.c - Main facility
|
||||
*
|
||||
* Copyright (C) 2002 Gergely Polonkai
|
||||
* Copyright (C) 2002-2006 P-Team Programmers' Group
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have recieved a copy of the GNU General Public License
|
||||
* along with this program; if not, write to Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA, 02111-1307, USA.
|
||||
*
|
||||
* GNU GPL is in doc/COPYING
|
||||
*/
|
||||
|
||||
#define USERV_MAIN
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "userv.h"
|
||||
#include "functions.h"
|
||||
|
||||
LST *laddr = NULL;
|
||||
CST *caddr = NULL;
|
||||
UST *auser = NULL;
|
||||
NST *nconn = NULL;
|
||||
SST *saddr = NULL;
|
||||
PST *paddr = NULL;
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int t;
|
||||
struct timeval tv;
|
||||
FILE *pf;
|
||||
|
||||
SetSignals();
|
||||
|
||||
if (daemon(1, 0) == -1) {
|
||||
Log(MT_ERROR, "Couldn't detach from controlling terminal");
|
||||
CleanUp(0);
|
||||
unlink("/var/run/userv.pid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((pf = fopen("/var/run/userv.pid", "w")) == NULL) {
|
||||
Log(MT_ERROR, "Unable to create pidfile");
|
||||
return -1;
|
||||
}
|
||||
fprintf(pf, "%d\n", getpid());
|
||||
fclose(pf);
|
||||
|
||||
if (gettimeofday(&tv, NULL) != 0) {
|
||||
Log(MT_ERROR, "Unable to get system time");
|
||||
unlink("/var/run/userv.pid");
|
||||
return -1;
|
||||
}
|
||||
srand(tv.tv_usec);
|
||||
|
||||
if (geteuid() != 0) {
|
||||
Log(MT_ERROR, "This server MUST be run as root!");
|
||||
unlink("/var/run/userv.pid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
t = ParseConfig();
|
||||
if (t != 0) {
|
||||
CleanUp(0);
|
||||
unlink("/var/run/userv.pid");
|
||||
}
|
||||
if (t > 0) {
|
||||
Log(MT_ERROR, "Erronous line at /etc/userv.conf:%d", t);
|
||||
return -1;
|
||||
} else if (t < 0) {
|
||||
switch (ParseConfig()) {
|
||||
case ERR_NOCF:
|
||||
Log(MT_ERROR, "Config file /etc/userv.conf doesn't exist");
|
||||
return -1;
|
||||
case ERR_NOMEM:
|
||||
Log(MT_ERROR, "Not enough memory while processing /etc/userv.conf");
|
||||
return -1;
|
||||
default:
|
||||
Log(MT_ERROR, "Undefined error\n");
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
if (StartListening() != ERR_OK) {
|
||||
Log(MT_ERROR, "Error occured while starting networking");
|
||||
CleanUp(0);
|
||||
unlink("/var/run/userv.pid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (MainLoop() != ERR_OK)
|
||||
Log(MT_ERROR, "Error during loop");
|
||||
|
||||
unlink("/var/run/userv.pid");
|
||||
|
||||
CleanUp(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
162
misc.c
Normal file
162
misc.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* UserServer/0.1
|
||||
* misc.c - Miscellanous functions
|
||||
*
|
||||
* Copyright (C) 2002 Gergely Polonkai
|
||||
* Copyright (C) 2002-2006 P-Team Programmers' Group
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have recieved a copy of the GNU General Public License
|
||||
* along with this program; if not, write to Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA, 02111-1307, USA.
|
||||
*
|
||||
* GNU GPL is in doc/COPYING
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "userv.h"
|
||||
#include "functions.h"
|
||||
|
||||
char *trim(char *text, char *spc) {
|
||||
int start, end;
|
||||
char *b;
|
||||
|
||||
if (spc) {
|
||||
for (start = 0; start < strlen(text); start++)
|
||||
if (!strchr(spc, *(text + start)))
|
||||
break;
|
||||
for (end = strlen(text) - 1; end >= 0; end--)
|
||||
if (!strchr(spc, *(text + end)))
|
||||
break;
|
||||
} else {
|
||||
for (start = 0; start < strlen(text); start++)
|
||||
if (!isspace(*(text + start)))
|
||||
break;
|
||||
for (end = strlen(text) - 1; end >= 0; end--)
|
||||
if (!isspace(*(text + end)))
|
||||
break;
|
||||
}
|
||||
if (end == -1)
|
||||
return NULL;
|
||||
|
||||
if ((b = malloc(end - start + 2)) == NULL)
|
||||
return NULL;
|
||||
memset(b, 0, end - start + 2);
|
||||
|
||||
strncpy(b, text + start, end - start + 1);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
int
|
||||
valid_ip(char *addr) {
|
||||
int i, np = 0, nn = 0;
|
||||
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
if (strlen(addr) > 15)
|
||||
return 0;
|
||||
|
||||
if (!isdigit(addr[0]))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < strlen(addr); i++) {
|
||||
if (*(addr + i) == '.')
|
||||
np++;
|
||||
if ((*(addr + i) != '.') && (!isdigit(*(addr + i))))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (np != 3)
|
||||
return 0;
|
||||
|
||||
np = 0;
|
||||
|
||||
for (i = 0; i < strlen(addr); i++) {
|
||||
if (*(addr + i) == '.') {
|
||||
if (np)
|
||||
return 0;
|
||||
np = 1;
|
||||
nn = 0;
|
||||
}
|
||||
if (*(addr + i) != '.') {
|
||||
np = 0;
|
||||
nn++;
|
||||
if (nn == 4)
|
||||
return 0;
|
||||
}
|
||||
if (i > 0)
|
||||
if ((*(addr + i - 1) == '0') && (*(addr + i) != '.'))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(addr, "0.0.0.0") == 0)
|
||||
return 0;
|
||||
|
||||
if (strcmp(addr, "255.255.255.255") == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
valid_user(char *name) {
|
||||
if (getpwnam(name) == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ip_allowed(char *IP) {
|
||||
CST *temp = caddr;
|
||||
while (temp) {
|
||||
if (strcmp(IP, temp->IP) == 0)
|
||||
return 1;
|
||||
temp = temp->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
user_allowed(char *uname) {
|
||||
UST *temp = auser;
|
||||
|
||||
if (strcmp(uname, "root") == 0)
|
||||
return 0;
|
||||
|
||||
while (temp) {
|
||||
if (strcmp(uname, temp->uname) == 0)
|
||||
return 1;
|
||||
temp = temp->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
IsNum(char *str) {
|
||||
int i;
|
||||
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < strlen(str); i++)
|
||||
if (!isdigit(*(str + i)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
645
networking.c
Normal file
645
networking.c
Normal file
@ -0,0 +1,645 @@
|
||||
/*
|
||||
* UserServer/0.1
|
||||
* networking.c - Handling network connections
|
||||
*
|
||||
* Copyright (C) 2002 Gergely Polonkai
|
||||
* Copyright (C) 2002-2006 P-Team Programmers' Group
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have recieved a copy of the GNU General Public License
|
||||
* along with this program; if not, write to Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA, 02111-1307, USA.
|
||||
*
|
||||
* GNU GPL is in doc/COPYING
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <crypt.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "userv.h"
|
||||
#include "functions.h"
|
||||
|
||||
fd_set master, readable;
|
||||
int maxfd = 0;
|
||||
|
||||
int
|
||||
AddConn(int type, int sfd, char *IP) {
|
||||
char *ip;
|
||||
|
||||
if ((ip = strdup(IP)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
|
||||
if (nconn) {
|
||||
NST *temp = nconn;
|
||||
while (temp->next)
|
||||
temp = temp->next;
|
||||
if ((temp->next = malloc(NSTS)) == NULL) {
|
||||
free(ip);
|
||||
return ERR_NOMEM;
|
||||
}
|
||||
temp->next->next = NULL;
|
||||
temp->next->IP = ip;
|
||||
temp->next->type = type;
|
||||
temp->next->sfd = sfd;
|
||||
temp->next->timeout = 0;
|
||||
temp->next->loggedin = 0;
|
||||
} else {
|
||||
if ((nconn = malloc(NSTS)) == NULL) {
|
||||
free(ip);
|
||||
return ERR_NOMEM;
|
||||
}
|
||||
nconn->next = NULL;
|
||||
nconn->IP = ip;
|
||||
nconn->type = type;
|
||||
nconn->sfd = sfd;
|
||||
nconn->timeout = 0;
|
||||
nconn->loggedin = 0;
|
||||
}
|
||||
FD_SET(sfd, &master);
|
||||
if (sfd > maxfd)
|
||||
maxfd = sfd;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void
|
||||
DelConn(int sfd) {
|
||||
NST *temp = nconn;
|
||||
NST *p = NULL;
|
||||
NST *n;
|
||||
|
||||
while (temp) {
|
||||
n = temp->next;
|
||||
if (temp->sfd == sfd) {
|
||||
if (temp->IP)
|
||||
free(temp->IP);
|
||||
if (sfd != -1)
|
||||
close(sfd);
|
||||
if (p)
|
||||
p->next = temp->next;
|
||||
else
|
||||
nconn = n;
|
||||
free(temp);
|
||||
FD_CLR(sfd, &master);
|
||||
return;
|
||||
}
|
||||
p = temp;
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Type(int sfd) {
|
||||
NST *temp = nconn;
|
||||
while (temp) {
|
||||
if (temp->sfd == sfd)
|
||||
return temp->type;
|
||||
temp = temp->next;
|
||||
}
|
||||
return CT_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
LoggedIn(int sfd) {
|
||||
NST *temp = nconn;
|
||||
while (temp) {
|
||||
if (temp->sfd == sfd)
|
||||
return temp->loggedin;
|
||||
temp = temp->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SetLogin(int sfd, char *uname) {
|
||||
if (uname) {
|
||||
char *un;
|
||||
NST *temp = nconn;
|
||||
|
||||
if ((un = strdup(uname)) == NULL)
|
||||
return ERR_NOMEM;
|
||||
else {
|
||||
while (temp) {
|
||||
if (temp->sfd == sfd) {
|
||||
temp->loggedin = 1;
|
||||
temp->uname = un;
|
||||
return ERR_OK;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_NOUSER;
|
||||
}
|
||||
|
||||
char *
|
||||
GetIP(int sfd) {
|
||||
NST *temp = nconn;
|
||||
|
||||
while (temp) {
|
||||
if (temp->sfd == sfd)
|
||||
return temp->IP;
|
||||
temp = temp->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
GetUser(int sfd) {
|
||||
NST *temp = nconn;
|
||||
|
||||
while (temp) {
|
||||
if (temp->sfd == sfd)
|
||||
return temp->uname;
|
||||
temp = temp->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
IncTimeout(int sfd) {
|
||||
NST *temp = nconn;
|
||||
while (temp) {
|
||||
if (temp->sfd == sfd) {
|
||||
temp->timeout++;
|
||||
return;
|
||||
}
|
||||
if (temp->timeout == 600) {
|
||||
Log(MT_MSG, "Timeout at %s", GetIP(sfd));
|
||||
DelConn(temp->sfd);
|
||||
return;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
StartListening(void) {
|
||||
{
|
||||
LST *temp;
|
||||
|
||||
FD_ZERO(&master);
|
||||
FD_ZERO(&readable);
|
||||
|
||||
temp = laddr;
|
||||
while (temp) if (temp->IP) {
|
||||
int sfd;
|
||||
struct sockaddr_in la;
|
||||
int yes = 1;
|
||||
|
||||
if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
return ERR_SOCKET;
|
||||
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
|
||||
return ERR_OPT;
|
||||
|
||||
la.sin_family = AF_INET;
|
||||
la.sin_addr.s_addr = inet_addr(temp->IP);
|
||||
la.sin_port = htons(8778);
|
||||
memset(&(la.sin_zero), 0, 8);
|
||||
|
||||
if (bind(sfd, (struct sockaddr *)&la, sizeof(la)) == -1)
|
||||
return ERR_BIND;
|
||||
|
||||
if (listen(sfd, 10) == -1)
|
||||
return ERR_LISTEN;
|
||||
|
||||
if (AddConn(CT_LISTEN, sfd, temp->IP) != ERR_OK)
|
||||
return ERR_NOMEM;
|
||||
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
SST *temp;
|
||||
|
||||
temp = saddr;
|
||||
while (temp) if (temp->IP) {
|
||||
int sfd;
|
||||
struct sockaddr_in la;
|
||||
int yes = 1;
|
||||
|
||||
if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
return ERR_SOCKET;
|
||||
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
|
||||
return ERR_OPT;
|
||||
|
||||
la.sin_family = AF_INET;
|
||||
la.sin_addr.s_addr = inet_addr(temp->IP);
|
||||
la.sin_port = htons(8777);
|
||||
memset(&(la.sin_zero), 0, 8);
|
||||
|
||||
if (bind(sfd, (struct sockaddr *)&la, sizeof(la)) == -1)
|
||||
return ERR_BIND;
|
||||
|
||||
if (listen(sfd, 10) == -1)
|
||||
return ERR_LISTEN;
|
||||
|
||||
if (AddConn(CT_CONFIG, sfd, temp->IP) != ERR_OK)
|
||||
return ERR_NOMEM;
|
||||
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Send(int sfd, char *msg, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, msg);
|
||||
vdprintf(sfd, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
int
|
||||
MainLoop(void) {
|
||||
struct timeval tv;
|
||||
|
||||
while (1) {
|
||||
int t;
|
||||
readable = master;
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
t = select(maxfd + 1, &readable, NULL, NULL, &tv);
|
||||
if (t != -1) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= maxfd; i++) {
|
||||
if (FD_ISSET(i, &readable)) {
|
||||
if (Type(i) == CT_LISTEN) {
|
||||
struct sockaddr_in ra;
|
||||
int al = sizeof(ra);
|
||||
int nfd;
|
||||
|
||||
if ((nfd = accept(i, (struct sockaddr *)&ra, &al)) != -1) {
|
||||
if (ip_allowed(inet_ntoa(ra.sin_addr))) {
|
||||
AddConn(CT_CLIENT, nfd, inet_ntoa(ra.sin_addr));
|
||||
Log(MT_MSG, "Connection from allowed IP %s", inet_ntoa(ra.sin_addr));
|
||||
Send(nfd, "R\n");
|
||||
} else {
|
||||
Send(nfd, "D\n");
|
||||
Log(MT_MSG, "Attempted connection from denied IP %s", inet_ntoa(ra.sin_addr));
|
||||
close(nfd);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Type(i) == CT_CONFIG) {
|
||||
struct sockaddr_in ra;
|
||||
int al = sizeof(ra);
|
||||
int nfd;
|
||||
|
||||
if ((nfd = accept(i, (struct sockaddr *)&ra, &al)) != -1) {
|
||||
if (ip_allowed(inet_ntoa(ra.sin_addr))) {
|
||||
PST *temp = paddr->next;
|
||||
Send(nfd, "P %s\n", paddr->IP);
|
||||
while (temp) {
|
||||
Send(nfd, "P %s\n", temp->IP);
|
||||
temp = temp->next;
|
||||
}
|
||||
Send(nfd, "S\n");
|
||||
close(nfd);
|
||||
Log(MT_MSG, "Sent configuration to %s", inet_ntoa(ra.sin_addr));
|
||||
} else {
|
||||
Send(nfd, "D\n");
|
||||
Log(MT_MSG, "Attempted connection from denied IP %s", inet_ntoa(ra.sin_addr));
|
||||
close(nfd);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Type(i) == CT_CLIENT) {
|
||||
int r;
|
||||
char buf[1024];
|
||||
|
||||
memset(&buf, 0, 1024);
|
||||
r = recv(i, &buf, 1023, 0);
|
||||
if (r == 0) {
|
||||
Log(MT_MSG, "Connection closed from %s", GetIP(i));
|
||||
DelConn(i);
|
||||
}
|
||||
if (r > 0) {
|
||||
char *line = trim(buf, NULL);
|
||||
if (line) {
|
||||
if (strncmp(line, "L ", 2) == 0) {
|
||||
if (LoggedIn(i))
|
||||
Send(i, "L\n");
|
||||
else {
|
||||
char *uname, *passw;
|
||||
int start;
|
||||
|
||||
for (start = 1; start < strlen(line); start++)
|
||||
if (isspace(*(line + start)))
|
||||
break;
|
||||
uname = trim(line + start, NULL);
|
||||
|
||||
for (start = 1; start < strlen(uname); start++)
|
||||
if (isspace(*(uname + start)))
|
||||
break;
|
||||
|
||||
passw = trim(uname + start, NULL);
|
||||
|
||||
for (start = 0; start < strlen(uname); start++)
|
||||
if (isspace(*(uname + start)))
|
||||
*(uname + start) = 0;
|
||||
|
||||
if (!uname || !passw)
|
||||
Send(i, "E\n");
|
||||
else {
|
||||
if (!user_allowed(uname)) {
|
||||
Log(MT_MSG, "Attempted login by denied user %s from %s", uname, GetIP(i));
|
||||
Send(i, "D\n");
|
||||
} else {
|
||||
if (pwcheck(uname, passw) != ERR_OK) {
|
||||
Log(MT_MSG, "Login with bad password by %s from %s", uname, GetIP(i));
|
||||
Send(i, "B\n");
|
||||
} else {
|
||||
if (SetLogin(i, uname) == ERR_OK) {
|
||||
Log(MT_MSG, "Successful login by %s at %s", uname, GetIP(i));
|
||||
Send(i, "S\n");
|
||||
} else {
|
||||
Log(MT_MSG, "Failed to log in user %s from %s", uname, GetIP(i));
|
||||
Send(i, "F\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strcmp(line, "Q") == 0) {
|
||||
Send(i, "S\n");
|
||||
Log(MT_MSG, "Quit from %s, by %s", GetIP(i), GetUser(i));
|
||||
DelConn(i);
|
||||
}
|
||||
if (strncmp(line, "U ", 2) == 0) {
|
||||
if (!LoggedIn(i))
|
||||
Send(i, "L\n");
|
||||
else {
|
||||
int start;
|
||||
char *param;
|
||||
|
||||
for (start = 2; start < strlen(line); start++)
|
||||
if (!isspace(*(line + start)))
|
||||
break;
|
||||
param = line + start;
|
||||
for (start = 0; start < strlen(param); start++)
|
||||
if (isspace(*(param + start)))
|
||||
break;
|
||||
*(param + start) = 0;
|
||||
if (!IsNum(param))
|
||||
Send(i, "E\n");
|
||||
else {
|
||||
uid_t uid = (uid_t)atoi(param);
|
||||
if (Is_UID_exist(uid))
|
||||
Send(i, "U\n");
|
||||
else
|
||||
Send(i, "F\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strncmp(line, "N ", 2) == 0) {
|
||||
if (!LoggedIn(i))
|
||||
Send(i, "L\n");
|
||||
else {
|
||||
int start;
|
||||
char *param;
|
||||
|
||||
for (start = 2; start < strlen(line); start++)
|
||||
if (!isspace(*(line + start)))
|
||||
break;
|
||||
param = line + start;
|
||||
for (start = 0; start < strlen(param); start++)
|
||||
if (isspace(*(param + start)))
|
||||
break;
|
||||
*(param + start) = 0;
|
||||
if (valid_user(param))
|
||||
Send(i, "U\n");
|
||||
else
|
||||
Send(i, "F\n");
|
||||
}
|
||||
}
|
||||
if (strncmp(line, "A ", 2) == 0) {
|
||||
if (!LoggedIn(i))
|
||||
Send(i, "L\n");
|
||||
else {
|
||||
int start;
|
||||
char *param;
|
||||
|
||||
for (start = 2; start < strlen(line); start++)
|
||||
if (!isspace(*(line + start)))
|
||||
break;
|
||||
param = trim(line + start, NULL);
|
||||
if (param) {
|
||||
char *uname, *c_uid, *tanar, *samba, *passwd, *comment;
|
||||
|
||||
uname = param;
|
||||
c_uid = strchr(uname, ':') + 1;
|
||||
if (c_uid - 1 == NULL)
|
||||
Send(i, "E\n");
|
||||
else {
|
||||
*(strchr(uname, ':')) = 0;
|
||||
tanar = strchr(c_uid, ':') + 1;
|
||||
if (tanar - 1 == NULL)
|
||||
Send(i, "E\n");
|
||||
else {
|
||||
*(strchr(c_uid, ':')) = 0;
|
||||
samba = strchr(tanar, ':') + 1;
|
||||
if (samba - 1 == NULL)
|
||||
Send(i, "E\n");
|
||||
else {
|
||||
*(strchr(tanar, ':')) = 0;
|
||||
passwd = strchr(samba, ':') + 1;
|
||||
if (passwd - 1 == NULL)
|
||||
Send(i, "E\n");
|
||||
else {
|
||||
*(strchr(samba, ':')) = 0;
|
||||
comment = strchr(passwd, ':') + 1;
|
||||
if (comment - 1 == NULL)
|
||||
Send(i, "E\n");
|
||||
else {
|
||||
*(strchr(passwd, ':')) = 0;
|
||||
if (!IsNum(c_uid))
|
||||
Send(i, "E\n");
|
||||
else {
|
||||
uid_t uid;
|
||||
|
||||
uid = (uid_t)atoi(c_uid);
|
||||
if (Is_UID_exist(uid) || valid_user(uname))
|
||||
Send(i, "U\n");
|
||||
else {
|
||||
if ((strcmp(tanar, "0") != 0) && (strcmp(tanar, "1") != 0) && (strcmp(samba, "0") != 0) && (strcmp(samba, "1") != 0))
|
||||
Send(i, "E\n");
|
||||
else {
|
||||
char s[13], *cpass, tempfilename[13], scriptfilename[13];
|
||||
FILE *tf, *sf;
|
||||
|
||||
if (strcmp(c_uid, "0") == 0) {
|
||||
Log(MT_MSG, "Trying to add user with uid 0 from %s by %s", GetIP(i), GetUser(i));
|
||||
Send(i, "F\n");
|
||||
} else {
|
||||
salt((char *)&s);
|
||||
cpass = crypt(passwd, s);
|
||||
tempname((char *)&tempfilename, 12);
|
||||
tempname((char *)&scriptfilename, 12);
|
||||
|
||||
if ((tf = fopen(tempfilename, "w")) == NULL) {
|
||||
Log(MT_ERROR, "Unable to create tempfile (by %s at %s)", GetUser(i), GetIP(i));
|
||||
Send(i, "F\n");
|
||||
} else {
|
||||
fprintf(tf, "%s\n%s\n", passwd, passwd);
|
||||
fclose(tf);
|
||||
|
||||
if ((sf = fopen(scriptfilename, "w")) == NULL) {
|
||||
Log(MT_ERROR, "Unabke to create scriptfile (by %s at %s)", GetUser(i), GetIP(i));
|
||||
Send(i, "F\n");
|
||||
} else {
|
||||
pid_t pid;
|
||||
|
||||
fprintf(sf, "/usr/sbin/useradd -u %s -g %s -s %s %s-c \"%s\" -p %s %s > /dev/null 2>&1\n", c_uid, (*tanar == '1') ? "tanar" : "tanulo", (*samba == '1') ? "/bin/bash" : "/bin/false", (*samba == '1') ? "-m " : "", comment, cpass, uname);
|
||||
fprintf(sf, "r1=$?\n");
|
||||
if (*samba == '1') {
|
||||
fprintf(sf, "/usr/bin/smbpasswd -a -s %s < %s > /dev/null 2>&1\n", uname, tempfilename);
|
||||
fprintf(sf, "r2=$?\n");
|
||||
fprintf(sf, "/usr/bin/smbpasswd -e %s > /dev/null 2>&1\n", uname);
|
||||
fprintf(sf, "r3=$?\n");
|
||||
fprintf(sf, "if [ $r1 != 0 -o $r2 != 0 -o $r3 != 0 ]; then\n");
|
||||
} else
|
||||
fprintf(sf, "if [ $r1 != 0 ]; then\n");
|
||||
fprintf(sf, " exit 1\n");
|
||||
fprintf(sf, "else\n");
|
||||
fprintf(sf, " exit 0\n");
|
||||
fprintf(sf, "fi\n");
|
||||
fclose(sf);
|
||||
|
||||
if ((pid = fork()) == 0)
|
||||
execl("/bin/sh", "sh", scriptfilename);
|
||||
else {
|
||||
int ec;
|
||||
|
||||
waitpid(pid, &ec, 0);
|
||||
if (ec == 0) {
|
||||
Log(MT_MSG, "Added user %s with uid %s from %s by %s", uname, c_uid, GetIP(i), GetUser(i));
|
||||
Send(i, "S\n");
|
||||
} else {
|
||||
Log(MT_MSG, "Failed to add user %s with uid %s from %s bye %s", uname, c_uid, GetIP(i), GetUser(i));
|
||||
Send(i, "F\n");
|
||||
}
|
||||
|
||||
unlink(scriptfilename);
|
||||
}
|
||||
}
|
||||
unlink(tempfilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strncmp(line, "D ", 2) == 0) {
|
||||
if (!LoggedIn(i))
|
||||
Send(i, "L\n");
|
||||
else {
|
||||
int start;
|
||||
char *uname;
|
||||
|
||||
for (start = 2; start < strlen(line); start++)
|
||||
if (!isspace(*(line + start)))
|
||||
break;
|
||||
|
||||
uname = line + start;
|
||||
for (start = 0; start < strlen(uname); start++)
|
||||
if (isspace(*(uname + start))) {
|
||||
*(uname + start) = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!valid_user(uname))
|
||||
Send(i, "E\n");
|
||||
else {
|
||||
FILE *sf;
|
||||
char scriptfilename[13];
|
||||
|
||||
tempname((char *)&scriptfilename, 12);
|
||||
if ((sf = fopen(scriptfilename, "w")) == NULL)
|
||||
Send(i, "F\n");
|
||||
else {
|
||||
pid_t pid;
|
||||
fprintf(sf, "userdel -r %s > /dev/null 2>&1\n", uname);
|
||||
fprintf(sf, "r=$?\n");
|
||||
fprintf(sf, "if [ $r = 12 -o $r = 0 ]; then\n");
|
||||
fprintf(sf, " r1=0\n");
|
||||
fprintf(sf, "else\n");
|
||||
fprintf(sf, " r1=1\n");
|
||||
fprintf(sf, "fi\n");
|
||||
fprintf(sf, "smbpasswd -x %s > /dev/null 2>&1\n", uname);
|
||||
fprintf(sf, "r2=$?\n");
|
||||
fprintf(sf, "if [ $r1 != 0 -o $r2 != 0 ]; then\n");
|
||||
fprintf(sf, " exit 1\n");
|
||||
fprintf(sf, "else\n");
|
||||
fprintf(sf, " exit 0\n");
|
||||
fprintf(sf, "fi\n");
|
||||
fclose(sf);
|
||||
|
||||
if ((pid = fork()) == 0) { //child
|
||||
execl("/bin/sh", "sh", scriptfilename);
|
||||
} else { //parent
|
||||
int ec;
|
||||
waitpid(pid, &ec, 0);
|
||||
if (ec == 0) {
|
||||
Log(MT_MSG, "Deleted user %s from %s by %s", uname, GetIP(i), GetUser(i));
|
||||
Send(i, "S\n");
|
||||
} else {
|
||||
Log(MT_MSG, "Failed to delete %s from %s by %s", uname, GetIP(i), GetUser(i));
|
||||
Send(i, "F\n");
|
||||
}
|
||||
unlink(scriptfilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
if (Type(i) == CT_CLIENT)
|
||||
IncTimeout(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
88
signal.c
Normal file
88
signal.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* UserServer/0.1
|
||||
* signal.c - Signal handling
|
||||
*
|
||||
* Copyright (C) 2002 Gergely Polonkai
|
||||
* Copyright (C) 2002-2006 P-Team Programmers' Group
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have recieved a copy of the GNU General Public License
|
||||
* along with this program; if not, write to Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA, 02111-1307, USA.
|
||||
*
|
||||
* GNU GPL is in doc/COPYING
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "userv.h"
|
||||
#include "functions.h"
|
||||
|
||||
int fcount = 0;
|
||||
|
||||
void
|
||||
rehash(int signum) {
|
||||
Log(MT_MSG, "Signal caught, rehashing...");
|
||||
CleanUp(0);
|
||||
ParseConfig();
|
||||
StartListening();
|
||||
}
|
||||
|
||||
void
|
||||
shutdown(int signum) {
|
||||
Log(MT_MSG, "Signal caught, shutting down...");
|
||||
CleanUp(0);
|
||||
unlink("/var/run/userv.pid");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
fatal(int signum) {
|
||||
if (signum == SIGSEGV)
|
||||
Log(MT_ERROR, "segv");
|
||||
fcount++;
|
||||
Log(MT_ERROR, "Fatal signal caught, terminating...");
|
||||
PrintContext;
|
||||
unlink("/var/run/userv.pid");
|
||||
if (fcount > 1)
|
||||
exit(1);
|
||||
CleanUp(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define SA(x, y) memset(&sa, 0, sizeof(sa)); \
|
||||
sa.sa_handler = (y); \
|
||||
sigaction(x, &sa, NULL)
|
||||
void
|
||||
SetSignals(void) {
|
||||
struct sigaction sa;
|
||||
|
||||
SA(SIGHUP, &rehash);
|
||||
SA(SIGINT, &shutdown);
|
||||
SA(SIGQUIT, &shutdown);
|
||||
SA(SIGILL, &fatal);
|
||||
SA(SIGABRT, &shutdown);
|
||||
SA(SIGFPE, &fatal);
|
||||
SA(SIGSEGV, &fatal);
|
||||
SA(SIGTERM, &shutdown);
|
||||
SA(SIGUSR1, SIG_IGN);
|
||||
SA(SIGUSR2, SIG_IGN);
|
||||
SA(SIGPIPE, SIG_IGN);
|
||||
SA(SIGCHLD, SIG_IGN);
|
||||
SA(SIGTTIN, SIG_IGN);
|
||||
SA(SIGTTOU, SIG_IGN);
|
||||
}
|
||||
#undef SA
|
||||
|
86
userv.h
Normal file
86
userv.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef US_USERV_H
|
||||
# define US_USERV_H
|
||||
|
||||
# define CONTEXT_DEBUG
|
||||
# ifdef CONTEXT_DEBUG
|
||||
# define Context n_Context(__FILE__, __LINE__)
|
||||
# define PrintContext n_PrintContext()
|
||||
# else
|
||||
# define Context
|
||||
# define PrintContext
|
||||
# endif
|
||||
|
||||
# define ERR_OK 0
|
||||
# define ERR_NOUSER -1
|
||||
# define ERR_NOSHADOW -2
|
||||
# define ERR_NOPASS -3
|
||||
# define ERR_BADPASS -4
|
||||
# define ERR_NOCF -5
|
||||
# define ERR_NOMEM -6
|
||||
# define ERR_NOLISTEN -7
|
||||
# define ERR_SOCKET -8
|
||||
# define ERR_OPT -9
|
||||
# define ERR_BIND -10
|
||||
# define ERR_LISTEN -11
|
||||
|
||||
# define CT_NONE 0
|
||||
# define CT_LISTEN 1
|
||||
# define CT_CLIENT 2
|
||||
# define CT_CONFIG 3
|
||||
|
||||
# define MT_NONE 0
|
||||
# define MT_ERROR 1
|
||||
# define MT_MSG 2
|
||||
|
||||
typedef struct L_Struct {
|
||||
char *IP;
|
||||
struct L_Struct *next;
|
||||
} LST;
|
||||
# define LSTS sizeof(LST)
|
||||
|
||||
typedef struct S_Struct {
|
||||
char *IP;
|
||||
struct S_Struct *next;
|
||||
} SST;
|
||||
# define SSTS sizeof(SST)
|
||||
|
||||
typedef struct C_Struct {
|
||||
char *IP;
|
||||
struct C_Struct *next;
|
||||
} CST;
|
||||
# define CSTS sizeof(CST)
|
||||
|
||||
typedef struct P_Struct {
|
||||
char *IP;
|
||||
struct P_Struct *next;
|
||||
} PST;
|
||||
# define PSTS sizeof(PST)
|
||||
|
||||
typedef struct U_Struct {
|
||||
char *uname;
|
||||
struct U_Struct *next;
|
||||
} UST;
|
||||
# define USTS sizeof(UST)
|
||||
|
||||
typedef struct N_Struct {
|
||||
int type;
|
||||
char *IP;
|
||||
int sfd;
|
||||
unsigned long timeout;
|
||||
int loggedin;
|
||||
char *uname;
|
||||
struct N_Struct *next;
|
||||
} NST;
|
||||
# define NSTS sizeof(NST)
|
||||
|
||||
# ifndef USERV_MAIN
|
||||
extern LST *laddr;
|
||||
extern CST *caddr;
|
||||
extern UST *auser;
|
||||
extern NST *nconn;
|
||||
extern SST *saddr;
|
||||
extern PST *paddr;
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user