diff options
author | ilsimo <ilsimo> | 2007-04-07 16:20:08 +0000 |
---|---|---|
committer | ilsimo <ilsimo> | 2007-04-07 16:20:08 +0000 |
commit | 9c4b9f8390c992a7b08fd487e17b6067571dfa52 (patch) | |
tree | b73d470ef843f79c8ba7421af963fa29e0a9dd2f | |
parent | e9a9c8dc97124148365ae1cc8d7c2044136fc720 (diff) | |
download | xrdp-proprietary-9c4b9f8390c992a7b08fd487e17b6067571dfa52.tar.gz xrdp-proprietary-9c4b9f8390c992a7b08fd487e17b6067571dfa52.zip |
added sessvc as session supervisor
first code for password changing
-rw-r--r-- | sesman/Makefile | 29 | ||||
-rw-r--r-- | sesman/auth.h | 29 | ||||
-rw-r--r-- | sesman/sesman.h | 4 | ||||
-rw-r--r-- | sesman/sesman.ini | 1 | ||||
-rw-r--r-- | sesman/session.c | 123 | ||||
-rw-r--r-- | sesman/session.h | 21 | ||||
-rw-r--r-- | sesman/sessvc.c | 68 | ||||
-rw-r--r-- | sesman/sig.c | 10 | ||||
-rw-r--r-- | sesman/tools/Makefile | 35 | ||||
-rw-r--r-- | sesman/tools/sesrun.c | 125 | ||||
-rw-r--r-- | sesman/verify_user.c | 150 |
11 files changed, 514 insertions, 81 deletions
diff --git a/sesman/Makefile b/sesman/Makefile index 293f5372..07d9efd3 100644 --- a/sesman/Makefile +++ b/sesman/Makefile @@ -6,8 +6,7 @@ SESMANOBJ = sesman.o config.o tcp.o sig.o session.o env.o \ scp.o scp_v0.o scp_v1.o thread.o lock.o \ $(LIBSCPOBJ) -SESRUNOBJ = sesrun.o config.o tcp.o lock.o \ - os_calls.o d3des.o list.o file.o log.o +SESSVCOBJ = sessvc.o os_calls.o DESTDIR = /usr/local/xrdp CFGDIR = /etc/xrdp @@ -16,14 +15,15 @@ MANDIR = /usr/local/man DOCDIR = /usr/doc/xrdp DEFINES = -DSESMAN_CFG_FILE=\"$(CFGDIR)/sesman.ini\" \ - -DSESMAN_PID_FILE=\"$(PIDDIR)/sesman.pid\" -DDEBUG + -DSESMAN_PID_FILE=\"$(PIDDIR)/sesman.pid\" \ + -DSESMAN_SESSVC_FILE=\"$(DESTDIR)/sessvc\" \ + -DDEBUG CFLAGS = -Wall -O2 -I../common -I/usr/include/nptl $(DEFINES) -LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread $(DEFINES) +LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread -ldl $(DEFINES) C_OS_FLAGS = $(CFLAGS) -c CC = gcc - all: pam tools nopam: no-pam tools @@ -31,35 +31,36 @@ nopam: no-pam tools kerberos: kerberos-base tools no-pam: $(SESMANOBJ) verify_user.o - $(CC) $(LDFLAGS) -o sesman $(SESMANOBJ) verify_user.o -ldl -lcrypt + $(CC) $(LDFLAGS) -o sesman $(SESMANOBJ) verify_user.o -lcrypt pam: $(SESMANOBJ) verify_user_pam.o - $(CC) $(LDFLAGS) -o sesman $(SESMANOBJ) verify_user_pam.o -ldl -lpam + $(CC) $(LDFLAGS) -o sesman $(SESMANOBJ) verify_user_pam.o -lpam pam_userpass: $(SESMANOBJ) verify_user_pam_userpass.o - $(CC) $(LDFLAGS) -o sesman $(SESMANOBJ) verify_user_pam_userpass.o -ldl -lpam -lpam_userpass + $(CC) $(LDFLAGS) -o sesman $(SESMANOBJ) verify_user_pam_userpass.o -lpam -lpam_userpass kerberos-base: $(SESMANOBJ) verify_user_kerberos.o - $(CC) $(LDFLAGS) -o sesman $(SESMANOBJ) verify_user_kerberos.o -ldl -lkrb5 + $(CC) $(LDFLAGS) -o sesman $(SESMANOBJ) verify_user_kerberos.o -lkrb5 + +sessvc: $(SESSVCOBJ) + $(CC) $(LDFLAGS) -o sessvc $(SESSVCOBJ) -tools: $(SESRUNOBJ) - $(CC) $(LDFLAGS) -o sesrun $(SESRUNOBJ) -ldl +tools: sessvc make -C tools clean: - rm -f $(SESMANOBJ) verify_user.o verify_user_pam.o verify_user_pam_userpass.o sesman sesrun.o sesrun + rm -f $(SESMANOBJ) verify_user.o verify_user_pam.o verify_user_pam_userpass.o sesman sesrun.o sesrun sessvc.o sessvc make -C tools clean install: install sesman $(DESTDIR)/sesman - install sesrun $(DESTDIR)/sesrun install startwm.sh $(DESTDIR)/startwm.sh install sesman.ini $(CFGDIR)/sesman.ini + install sessvc $(DESTDIR)/sessvc make -C tools install installdeb: install sesman $(DESTDIRDEB)/usr/lib/xrdp/sesman - install sesrun $(DESTDIRDEB)/usr/lib/xrdp/sesrun install startwm.sh $(DESTDIRDEB)/usr/lib/xrdp/startwm.sh install sesman.ini $(DESTDIRDEB)/etc/xrdp/sesman.ini diff --git a/sesman/auth.h b/sesman/auth.h index cff0dabb..bb23a819 100644 --- a/sesman/auth.h +++ b/sesman/auth.h @@ -22,7 +22,7 @@ * @file auth.h * @brief User authentication definitions * @author Jay Sorg - * + * */ #ifndef AUTH_H @@ -70,4 +70,31 @@ auth_end(long in_val); int DEFAULT_CC auth_set_env(long in_val); + +#define AUTH_PWD_CHG_OK 0 +#define AUTH_PWD_CHG_CHANGE 1 +#define AUTH_PWD_CHG_CHANGE_MANDATORY 2 +#define AUTH_PWD_CHG_NOT_NOW 3 +#define AUTH_PWD_CHG_ERROR 4 + +/** + * + * @brief FIXME + * @param in_val + * @return 0 on success, 1 on failure + * + */ +int DEFAULT_CC +auth_check_pwd_chg(char* user); + +/** + * + * @brief FIXME + * @param in_val + * @return 0 on success, 1 on failure + * + */ +int DEFAULT_CC +auth_change_pwd(char* user, char* newpwd); + #endif diff --git a/sesman/sesman.h b/sesman/sesman.h index 8761f5f4..774e2aad 100644 --- a/sesman/sesman.h +++ b/sesman/sesman.h @@ -50,4 +50,8 @@ #define SESMAN_PID_FILE "./sesman.pid" #endif +#ifndef SESMAN_SESSVC_FILE + #define SESMAN_SESSVC_FILE "./sessvc" +#endif + #endif diff --git a/sesman/sesman.ini b/sesman/sesman.ini index 48a8a748..2cecd57a 100644 --- a/sesman/sesman.ini +++ b/sesman/sesman.ini @@ -1,4 +1,5 @@ [Globals] +ListenAddress=127.0.0.1 ListenPort=3350 EnableUserWindowManager=1 UserWindowManager=startwm.sh diff --git a/sesman/session.c b/sesman/session.c index 0739ca21..a0ca44f3 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -22,12 +22,15 @@ * @file session.c * @brief Session management code * @author Jay Sorg, Simone Fedele - * + * */ #include "sesman.h" #include "libscp_types.h" +//#include "unistd.h" +//#include "stdio.h" + extern unsigned char g_fixedkey[8]; extern struct config_sesman g_cfg; /* config.h */ struct session_chain* g_sessions; @@ -55,7 +58,7 @@ session_get_bydata(char* name, int width, int height, int bpp) lock_chain_release(); return tmp->item; } - tmp = tmp->next; + tmp = tmp->next; } /*THREAD-FIX release chain lock */ @@ -109,6 +112,46 @@ x_server_running(int display) return x_running; } +static void DEFAULT_CC +session_start_sessvc(int xpid, int wmpid, long data) +{ + struct list* sessvc_params; + char text[256]; + char wmpid_str[25]; + char xpid_str[25]; + + /* new style waiting for clients */ + g_sprintf(wmpid_str, "%d", wmpid); + g_sprintf(xpid_str, "%d", xpid); + log_message(LOG_LEVEL_INFO, "starting sessvc xpid=%s wmpid=%s ",xpid_str, wmpid_str); + + sessvc_params = list_create(); + sessvc_params->auto_free = 1; + + /* building parameters */ + list_add_item(sessvc_params, (long)g_strdup(SESMAN_SESSVC_FILE)); + list_add_item(sessvc_params, (long)g_strdup(xpid_str)); + list_add_item(sessvc_params, (long)g_strdup(wmpid_str)); + list_add_item(sessvc_params, 0); /* mandatory */ + + g_execvp(SESMAN_SESSVC_FILE, ((char**)sessvc_params->items)); + list_delete(sessvc_params); + //#warning FIXME sessvc PATH!! + //execlp("/usr/local/xrdp/sessvc", "/usr/local/xrdp/sessvc", xpid_str, wmpid_str, 0); + + /* if we get here there's some error */ + //strerror_r(errno, text, 255); + log_message(LOG_LEVEL_ALWAYS, "Error in execlp for sessvc: %s", text); + + /* keep the old waitpid if some error occurs during execlp */ + g_waitpid(wmpid); + g_sigterm(xpid); + g_sigterm(wmpid); + g_sleep(1000); + auth_end(data); + g_exit(0); +} + /******************************************************************************/ int DEFAULT_CC session_start(int width, int height, int bpp, char* username, char* password, @@ -181,7 +224,7 @@ for user %s denied", username); if (pid == -1) { } - else if (pid == 0) /* child */ + else if (pid == 0) /* child sesman */ { g_unset_signals(); auth_start_session(data, display); @@ -192,7 +235,7 @@ for user %s denied", username); if (wmpid == -1) { } - else if (wmpid == 0) /* child */ + else if (wmpid == 0) /* child (child sesman) xserver */ { /* give X a bit to start */ g_sleep(1000); @@ -213,7 +256,7 @@ for user %s denied", username); so we try running the default window manager */ g_sprintf(text, "%s/%s", cur_dir, g_cfg.default_wm); g_execlp3(text, g_cfg.default_wm, 0); - + /* still a problem starting window manager just start xterm */ g_execlp3("xterm", "xterm", 0); /* should not get here */ @@ -222,7 +265,7 @@ for user %s denied", username); username, g_getpid()); g_exit(0); } - else /* parent */ + else /* parent (child sesman) */ { xpid = g_fork(); if (xpid == -1) @@ -285,22 +328,18 @@ for user %s denied", username); username, g_getpid()); g_exit(1); } - else /* parent */ + else /* parent (child sesman)*/ { - g_waitpid(wmpid); - g_sigterm(xpid); - g_sigterm(wmpid); - g_sleep(1000); - auth_end(data); - g_exit(0); + /* new style waiting for clients */ + session_start_sessvc(xpid, wmpid, data); } } } - else /* parent */ + else /* parent sesman process */ { /* let the other threads go on */ lock_fork_release(); - + temp->item->pid = pid; temp->item->display = display; temp->item->width = width; @@ -316,14 +355,14 @@ for user %s denied", username); temp->item->type=type; temp->item->status=SESMAN_SESSION_STATUS_ACTIVE; - /*THREAD-FIX lock the chain*/ + /*THREAD-FIX lock the chain*/ lock_chain_acquire(); temp->next=g_sessions; g_sessions=temp; g_session_count++; /*THERAD-FIX free the chain*/ lock_chain_release(); - + g_sleep(5000); } return display; @@ -340,7 +379,7 @@ SESMAN_SESSION_STATUS_DISCONNECTED 3 struct session_item { char name[256]; - int pid; + int pid; int display; int width; int height; @@ -350,8 +389,8 @@ struct session_item / * unsigned char status; unsigned char type; - * / - + * / + / * time_t connect_time; time_t disconnect_time; @@ -372,13 +411,13 @@ session_kill(int pid) { struct session_chain* tmp; struct session_chain* prev; - + /*THREAD-FIX require chain lock */ lock_chain_acquire(); - + tmp=g_sessions; prev=0; - + while (tmp != 0) { if (tmp->item == 0) @@ -389,7 +428,7 @@ session_kill(int pid) { /* prev does no exist, so it's the first element - so we set g_sessions */ - g_sessions = tmp->next; + g_sessions = tmp->next; } else { @@ -434,6 +473,36 @@ session_kill(int pid) } /******************************************************************************/ +void DEFAULT_CC +session_sigkill_all() +{ + struct session_chain* tmp; + + /*THREAD-FIX require chain lock */ + lock_chain_acquire(); + + tmp=g_sessions; + + while (tmp != 0) + { + if (tmp->item == 0) + { + log_message(LOG_LEVEL_ERROR, "found null session descriptor!"); + } + else + { + g_sigterm(tmp->item->pid); + } + + /* go on */ + tmp=tmp->next; + } + + /*THREAD-FIX release chain lock */ + lock_chain_release(); +} + +/******************************************************************************/ struct session_item* DEFAULT_CC session_get_bypid(int pid) { @@ -480,7 +549,7 @@ session_get_byuser(char* user, int* cnt) int index; count=0; - + /*THREAD-FIX require chain lock */ lock_chain_acquire(); @@ -492,7 +561,7 @@ session_get_byuser(char* user, int* cnt) { count++; } - + /* go on */ tmp=tmp->next; } @@ -533,7 +602,7 @@ session_get_byuser(char* user, int* cnt) tmp=tmp->next; index++; } - + /*THREAD-FIX release chain lock */ lock_chain_release(); (*cnt)=count; diff --git a/sesman/session.h b/sesman/session.h index 339aeab6..dd3e531c 100644 --- a/sesman/session.h +++ b/sesman/session.h @@ -22,7 +22,7 @@ * @file session.h * @brief Session management definitions * @author Jay Sorg, Simone Fedele - * + * */ @@ -97,21 +97,30 @@ session_start(int width, int height, int bpp, char* username, char* password, * * @brief kills a session * @param pid the pid of the session to be killed - * @return - * + * @return + * */ int DEFAULT_CC session_kill(int pid); /** * + * @brief sends sigkill to all sessions + * @return + * + */ +void DEFAULT_CC +session_sigkill_all(); + +/** + * * @brief retrieves a session's descriptor * @param pid the session pid * @return a pointer to the session descriptor on success, NULL otherwise * */ struct session_item* DEFAULT_CC -session_get_bypid(int pid); +session_get_bypid(int pid); /** * @@ -120,8 +129,8 @@ session_get_bypid(int pid); * @return a pointer to the session descriptor on success, NULL otherwise * */ -struct SCP_DISCONNECTED_SESSION* -session_get_byuser(char* user, int* cnt); +struct SCP_DISCONNECTED_SESSION* +session_get_byuser(char* user, int* cnt); #endif diff --git a/sesman/sessvc.c b/sesman/sessvc.c new file mode 100644 index 00000000..2792ac7e --- /dev/null +++ b/sesman/sessvc.c @@ -0,0 +1,68 @@ +/* + This program is free software; you can redistribute it and/or modify + it under the terms of the 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 received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + xrdp: A Remote Desktop Protocol server. + Copyright (C) Jay Sorg 2005-2007 +*/ + +/** + * + * @file sessvc.c + * @brief Session supervisor + * @author Simone Fedele + * + */ + +#include "os_calls.h" +#include "arch.h" +#include "log.h" + +#include <sys/types.h> +#include <errno.h> + +pid_t wm_pid; +pid_t x_pid; + +void DEFAULT_CC +signal_handler(int sig) +{ + g_sigterm(x_pid); + g_sigterm(wm_pid); + g_exit(0); +} + +/******************************************************************************/ +int DEFAULT_CC +main(int argc, char** argv) +{ + int ret=0; + + x_pid = g_atoi(argv[1]); + wm_pid = g_atoi(argv[2]); + + g_printf("\n[sessvc] Setting signal handler\n"); + g_signal(9, signal_handler); /* SIGKILL */ + g_signal(15, signal_handler); /* SIGTERM */ + g_signal(17, signal_handler); /* SIGCHLD */ + + g_printf("\n[sessvc] Waiting for X (pid %d) and WM (pid %d)\n", x_pid, wm_pid); + + ret = g_waitpid(wm_pid); + g_sigterm(x_pid); + + g_printf("\n[sessvc] WM is dead (waitpid said %d, errno is %d). exiting...\n", ret, errno); + return 0; +} + diff --git a/sesman/sig.c b/sesman/sig.c index b69f6f27..f66827cd 100644 --- a/sesman/sig.c +++ b/sesman/sig.c @@ -22,7 +22,7 @@ * @file sig.c * @brief signal handling functions * @author Jay Sorg, Simone Fedele - * + * */ #include "sesman.h" @@ -49,6 +49,8 @@ sig_sesman_shutdown(int sig) g_tcp_close(g_sck); + session_sigkill_all(); + g_file_delete(SESMAN_PID_FILE); } @@ -65,14 +67,14 @@ sig_sesman_reload_cfg(int sig) LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid); return; } - + if (config_read(&cfg) != 0) { log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg"); return; } g_cfg = cfg; - + log_message(LOG_LEVEL_INFO, "configuration reloaded"); } @@ -103,7 +105,7 @@ sig_handler_thread(void* arg) sigset_t waitmask; /* mask signals to be able to wait for them... */ - sigfillset(&sigmask); + sigfillset(&sigmask); /* it is a good idea not to block SIGILL SIGSEGV */ /* SIGFPE -- see sigaction(2) NOTES */ pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask); diff --git a/sesman/tools/Makefile b/sesman/tools/Makefile index 51eda709..d79f9cd1 100644 --- a/sesman/tools/Makefile +++ b/sesman/tools/Makefile @@ -1,20 +1,26 @@ -# sesman makefile +# sesman tools makefile SESTESTOBJ = sestest.o tcp.o \ os_calls.o d3des.o list.o file.o \ - libscp_v1c.o + libscp_v1c.o + +SESRUNOBJ = sesrun.o config.o tcp.o \ + os_calls.o d3des.o list.o file.o log.o DEFINES = -DLIBSCP_CLIENT CFLAGS = -Wall -O2 -I../../common -I../ -I/usr/include/nptl $(DEFINES) -#LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread -ldl $(DEFINES) -LDFLAGS = -L /usr/gnu/lib -ldl $(DEFINES) +LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread -ldl $(DEFINES) +#LDFLAGS = -L /usr/gnu/lib -ldl $(DEFINES) C_OS_FLAGS = $(CFLAGS) -c -g CC = gcc -all: sestest +all: stest srun + +stest: $(SESTESTOBJ) + $(CC) $(LDFLAGS) -o sestest $(SESTESTOBJ) -sestest: $(SESTESTOBJ) - $(CC) $(LDFLAGS) -o sestest $(SESTESTOBJ) +srun: $(SESRUNOBJ) + $(CC) $(LDFLAGS) -o sesrun $(SESRUNOBJ) os_calls.o: ../../common/os_calls.c $(CC) $(C_OS_FLAGS) ../../common/os_calls.c @@ -28,14 +34,25 @@ list.o: ../../common/list.c file.o: ../../common/file.c $(CC) $(C_OS_FLAGS) ../../common/file.c +log.o: ../../common/file.c + $(CC) $(C_OS_FLAGS) ../../common/log.c + tcp.o: ../tcp.c $(CC) $(C_OS_FLAGS) ../tcp.c +config.o: ../config.c + $(CC) $(C_OS_FLAGS) ../config.c + libscp_v1c.o: ../libscp_v1c.c $(CC) $(C_OS_FLAGS) ../libscp_v1c.c clean: - rm $(SESTESTOBJ) sestest + rm *.o sestest sesrun install: - #install + install sesrun $(DESTDIR)/sesrun + install sestest $(DESTDIR)/sestest + +installdeb: + install sesrun $(DESTDIRDEB)/usr/lib/xrdp/sesrun + install sestest $(DESTDIRDEB)/usr/lib/xrdp/sestest diff --git a/sesman/tools/sesrun.c b/sesman/tools/sesrun.c new file mode 100644 index 00000000..22ccf138 --- /dev/null +++ b/sesman/tools/sesrun.c @@ -0,0 +1,125 @@ +/* + This program is free software; you can redistribute it and/or modify + it under the terms of the 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 received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + xrdp: A Remote Desktop Protocol server. + Copyright (C) Jay Sorg 2005-2007 +*/ + +/** + * + * @file sesrun.c + * @brief An utility to start a session + * @author Jay Sorg, Simone Fedele + * + */ + +#include "sesman.h" + +int g_sck; +int g_pid; +struct config_sesman g_cfg; /* config.h */ + +/******************************************************************************/ +int DEFAULT_CC +main(int argc, char** argv) +{ + int sck; + int code; + int i; + int size; + int version; + int width; + int height; + int bpp; + int display; + struct stream* in_s; + struct stream* out_s; + char* username; + char* password; + long data; + + if (0 != config_read(&g_cfg)) + { + g_printf("sesrun: error reading config. quitting.\n"); + return 1; + } + + g_pid = g_getpid(); + if (argc == 1) + { + g_printf("xrdp session starter v0.1\n"); + g_printf("\nusage:\n"); + g_printf("sesrun <server> <username> <password> <width> <height> <bpp>\n"); + } + else if (argc == 7) + { + username = argv[2]; + password = argv[3]; + width = g_atoi(argv[4]); + height = g_atoi(argv[5]); + bpp = g_atoi(argv[6]); + make_stream(in_s); + init_stream(in_s, 8192); + make_stream(out_s); + init_stream(out_s, 8192); + sck = g_tcp_socket(); + if (g_tcp_connect(sck, argv[1], "3350") == 0) + { + s_push_layer(out_s, channel_hdr, 8); + out_uint16_be(out_s, 0); /* code */ + i = g_strlen(username); + out_uint16_be(out_s, i); + out_uint8a(out_s, username, i); + i = g_strlen(password); + out_uint16_be(out_s, i); + out_uint8a(out_s, password, i); + out_uint16_be(out_s, width); + out_uint16_be(out_s, height); + out_uint16_be(out_s, bpp); + s_mark_end(out_s); + s_pop_layer(out_s, channel_hdr); + out_uint32_be(out_s, 0); /* version */ + out_uint32_be(out_s, out_s->end - out_s->data); /* size */ + tcp_force_send(sck, out_s->data, out_s->end - out_s->data); + if (tcp_force_recv(sck, in_s->data, 8) == 0) + { + in_uint32_be(in_s, version); + in_uint32_be(in_s, size); + init_stream(in_s, 8192); + if (tcp_force_recv(sck, in_s->data, size - 8) == 0) + { + if (version == 0) + { + in_uint16_be(in_s, code); + if (code == 3) + { + in_uint16_be(in_s, data); + in_uint16_be(in_s, display); + g_printf("ok %d display %d\n", data, display); + } + } + } + } + } + else + { + g_printf("connect error\n"); + } + g_tcp_close(sck); + free_stream(in_s); + free_stream(out_s); + } + return 0; +} diff --git a/sesman/verify_user.c b/sesman/verify_user.c index c7c57616..d2152e71 100644 --- a/sesman/verify_user.c +++ b/sesman/verify_user.c @@ -22,7 +22,7 @@ * @file verify_user.c * @brief Authenticate user using standard unix passwd/shadow system * @author Jay Sorg, Simone Fedele - * + * */ #include "sesman.h" @@ -41,6 +41,9 @@ extern struct config_sesman g_cfg; static int DEFAULT_CC +auth_crypt_pwd(char* pwd, char* pln, char* crp); + +static int DEFAULT_CC auth_account_disabled(struct spwd* stp); /******************************************************************************/ @@ -130,9 +133,6 @@ auth_set_env(long in_val) return 0; } -#define AUTH_NO_PWD_CHANGE 0 -#define AUTH_PWD_CHANGE 1 - /******************************************************************************/ int DEFAULT_CC auth_check_pwd_chg(char* user) @@ -145,43 +145,153 @@ auth_check_pwd_chg(char* user) spw = getpwnam(user); if (spw == 0) { - return AUTH_NO_PWD_CHANGE; + return AUTH_PWD_CHG_ERROR; } if (g_strncmp(spw->pw_passwd, "x", 3) != 0) { /* old system with only passwd */ - return AUTH_NO_PWD_CHANGE; + return AUTH_PWD_CHG_OK; } - + /* the system is using shadow */ stp = getspnam(user); if (stp == 0) { - return AUTH_NO_PWD_CHANGE; + return AUTH_PWD_CHG_ERROR; } - + /* check if we need a pwd change */ now=g_time1(); today=now/SECS_PER_DAY; - + if (today >= (stp->sp_lstchg + stp->sp_max - stp->sp_warn)) { - return AUTH_PWD_CHANGE; + return AUTH_PWD_CHG_CHANGE; } - + + if (today >= (stp->sp_lstchg + stp->sp_max)) + { + return AUTH_PWD_CHG_CHANGE_MANDATORY; + } + if (today < ((stp->sp_lstchg)+(stp->sp_min))) { /* cannot change pwd for now */ - return AUTH_NO_PWD_CHANGE; + return AUTH_PWD_CHG_NOT_NOW; + } + + return AUTH_PWD_CHG_OK; +} + +int DEFAULT_CC +auth_change_pwd(char* user, char* newpwd) +{ + struct passwd* spw; + struct spwd* stp; + char hash[35] = ""; + long today; + + FILE* fd; + + if (0 != lckpwdf()) + { + return 1; + } + + /* open passwd */ + spw = getpwnam(user); + if (spw == 0) + { + return 1; + } + + if (g_strncmp(spw->pw_passwd, "x", 3) != 0) + { + /* old system with only passwd */ + if (auth_crypt_pwd(spw->pw_passwd, newpwd, hash) != 0) + { + ulckpwdf(); + return 1; + } + + spw->pw_passwd=g_strdup(hash); + fd = fopen("/etc/passwd", "rw"); + putpwent(spw, fd); + } + else + { + /* the system is using shadow */ + stp = getspnam(user); + if (stp == 0) + { + return 1; + } + + /* old system with only passwd */ + if (auth_crypt_pwd(stp->sp_pwdp, newpwd, hash) != 0) + { + ulckpwdf(); + return 1; + } + + stp->sp_pwdp = g_strdup(hash); + today = g_time1() / SECS_PER_DAY; + stp->sp_lstchg = today; + stp->sp_expire = today + stp->sp_max + stp->sp_inact; + fd = fopen("/etc/shadow", "rw"); + putspent(stp, fd); + } + + ulckpwdf(); + return 0; +} + +/** + * + * @brief Password encryption + * @param pwd Old password + * @param pln Plaintext new password + * @param crp Crypted new password + * + */ + +static int DEFAULT_CC +auth_crypt_pwd(char* pwd, char* pln, char* crp) +{ + char salt[13] = "$1$"; + int saltcnt = 0; + char* encr; + + if (g_strncmp(pwd, "$1$", 3) == 0) + { + /* gnu style crypt(); */ + saltcnt = 3; + while ((pwd[saltcnt] != '$') && (saltcnt < 11)) + { + salt[saltcnt] = pwd[saltcnt]; + saltcnt++; + } + salt[saltcnt] = '$'; + salt[saltcnt + 1] = '\0'; + } + else + { + /* classic two char salt */ + salt[0] = pwd[0]; + salt[1] = pwd[1]; + salt[2] = '\0'; } - - return AUTH_NO_PWD_CHANGE; + + encr = crypt(pln, salt); + g_strncpy(crp, encr, 34); + + return 0; } /** * * @return 1 if the account is disabled, 0 otherwise - * + * */ static int DEFAULT_CC auth_account_disabled(struct spwd* stp) @@ -193,7 +303,7 @@ auth_account_disabled(struct spwd* stp) /* if an invalid struct was passed we assume a disabled account */ return 1; } - + today=g_time1()/SECS_PER_DAY; LOG_DBG("last %d",stp->sp_lstchg); @@ -208,12 +318,12 @@ auth_account_disabled(struct spwd* stp) { return 1; } - + if (today >= (stp->sp_lstchg+stp->sp_max+stp->sp_inact)) { return 1; } - return 0; + return 0; } - + |