diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2005-08-29 14:29:07 +0000 |
---|---|---|
committer | Aris Adamantiadis <aris@0xbadc0de.be> | 2005-08-29 14:29:07 +0000 |
commit | bcb6bf25fa132421672d0782b9bfdb82fd2c6600 (patch) | |
tree | 90e46158b0fed3063dfd752a7f27bd6f49f827da /sftp_server/main.c | |
parent | ddd650b3bd10fa3f2198bc7c63bc75eb3ad0cdc5 (diff) | |
download | libssh-bcb6bf25fa132421672d0782b9bfdb82fd2c6600.tar.gz libssh-bcb6bf25fa132421672d0782b9bfdb82fd2c6600.tar.xz libssh-bcb6bf25fa132421672d0782b9bfdb82fd2c6600.zip |
the server now does the chroot and change uid.
There is also an option "nopassword" for ftp users.
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@25 7dcaeef0-15fb-0310-b436-a5af3365683c
Diffstat (limited to 'sftp_server/main.c')
-rw-r--r-- | sftp_server/main.c | 84 |
1 files changed, 79 insertions, 5 deletions
diff --git a/sftp_server/main.c b/sftp_server/main.c index 7b276d2..949b997 100644 --- a/sftp_server/main.c +++ b/sftp_server/main.c @@ -35,6 +35,7 @@ MA 02111-1307, USA. */ #include <stdio.h> #include <signal.h> #include <security/pam_appl.h> +#include <pwd.h> #include "server.h" @@ -81,7 +82,59 @@ int password_conv(int num_msg, const struct pam_message **msg, return PAM_SUCCESS; } - +/* postauth_conf returns -1 on error, else 0 */ +int postauth_conf(char *user){ + /* first, find a chroot if any */ + char *root,*ptr; + char *char_uid; + char buffer[256]; + int uid; + struct passwd *pw=getpwnam(user); + root=user_chroot(user); + if(root){ + if((ptr=strstr(root,"$HOME"))){ + if(!pw) + return -1; // this user has no user directory + *ptr=0; + snprintf(buffer,sizeof(buffer),"%s%s/%s", + root,pw->pw_dir,ptr+strlen("$HOME")); + } + else + snprintf(buffer,sizeof(buffer),"%s",root); + } + /* we don't chroot right now because we still need getpwnam() */ + char_uid=user_uid(user); + if(!char_uid){ + if(!pw) + return -1; // user doesn't exist ! + char_uid=user; + } + uid=atoi(char_uid); + if(uid==0 && char_uid[0]!=0){ + pw=getpwnam(char_uid); + if(!pw) + return -1; + uid=pw->pw_uid; + } + if(root && chroot(buffer)){ + return -1; // cannot chroot + } + if(root){ + chdir("/"); + } else { + if(pw) + chdir(pw->pw_dir); + else + chdir("/"); + } + if(setuid(uid)){ + return -1; // cannot setuid + } + return 0; +} + + + struct pam_conv pam_conv ={ password_conv, NULL }; /* returns 1 if authenticated, 0 if failed, -1 if you must leave */ @@ -101,6 +154,8 @@ int auth_password(char *user, char *password){ memset(password,0,strlen(password)); if(ret==PAM_SUCCESS){ pam_end(pamh,PAM_SUCCESS); + if(postauth_conf(user)) + return -1; return 1; } else { pam_end(pamh,PAM_AUTH_ERR); @@ -469,13 +524,32 @@ int do_auth(SSH_SESSION *session){ ssh_say(1,"Auth refused\n"); break; } - if(auth==1) + if(auth==1){ break; + } else { + ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD); + ssh_message_reply_default(message); + } + break; // not authenticated, send default message case SSH_AUTH_NONE: - //ssh_message_auth_reply_success(message,0); - //auth=1; - //break; + if(user_nopassword(ssh_message_auth_user(message))){ + if(postauth_conf(ssh_message_auth_user(message))==0){ + ssh_message_auth_reply_success(message,0); + auth=1; + ssh_say(1,"Authentication success for %s(no password)\n", + ssh_message_auth_user(message)); + break; + } else { + ssh_say(1,"Post-auth failed\n"); + ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD); + ssh_message_reply_default(message); + } + } else { + ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD); + ssh_message_reply_default(message); + } + break; default: ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD); ssh_message_reply_default(message); |