summaryrefslogtreecommitdiffstats
path: root/hw1/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw1/session.c')
-rw-r--r--hw1/session.c84
1 files changed, 83 insertions, 1 deletions
diff --git a/hw1/session.c b/hw1/session.c
index dd416a8..40a0e65 100644
--- a/hw1/session.c
+++ b/hw1/session.c
@@ -8,6 +8,7 @@
#include "socktool.h"
#include "connection.h"
#include "server.h"
+#include "basic-array.h"
#include <errno.h>
#include <grp.h>
@@ -92,7 +93,7 @@ int ras_session_read_header (RasSession* session) {
next = oneline + onelinelen;
} else {
*space = '\0';
- for (space++; *space != '\0' && *space != ' '; space++);
+ for (space++; *space == '\0' && *space == ' '; space++);
next = space;
}
@@ -110,6 +111,87 @@ int ras_session_read_header (RasSession* session) {
return -1;
}
+ struct passwd* login_user = NULL;
+ if (*next != '\0') {
+ login_user = getpwnam (next);
+ if (login_user == NULL) {
+ const char baduser_msg[] = "Error: User not found.\n";
+ const int baduser_len = STATIC_STRLEN (baduser_msg);
+ ras_socktool_write_string (RAS_CONN (session)->fd, baduser_msg, baduser_len);
+ ras_session_log (session, "user %s cannot be found", next);
+ free (oneline);
+ return -1;
+ }
+ }
+
+ free (oneline);
+
+ if (RAS_CONN (session)->perm == RAS_CONN_PERM_RESTRICTED) {
+ uid_t real_uid = getuid ();
+ if (login_user != NULL && login_user->pw_uid != real_uid) {
+ const char rest_msg[] = "Error: You are not permitted to login from here.\n";
+ const int rest_len = STATIC_STRLEN (rest_msg);
+ ras_socktool_write_string (RAS_CONN (session)->fd, rest_msg, rest_len);
+ ras_session_log (session, "user %s is not permitted", login_user->pw_name);
+ return -1;
+ }
+ setuid (real_uid);
+ } else {
+ const char sufail_msg[] = "Error: Unable to change the user credential.\n";
+ const int sufail_len = STATIC_STRLEN (sufail_msg);
+ int rval;
+
+#if defined(HAVE_INITGROUPS)
+ rval = initgroups (login_user->pw_name, login_user->pw_gid);
+#elif defined(HAVE_SETGROUPS)
+ struct group* groupentry;
+ Array* grouplist = array_create (sizeof (gid_t), 1);
+ int errno_saved;
+
+ array_pushback (grouplist, &login_user->pw_gid);
+ setgrent ();
+ while ((groupentry = getgrent ()) != NULL) {
+ for (int i = 0; groupentry->gr_mem[i] != NULL; i++) {
+ if (strcmp (groupentry->gr_mem[i], login_user->pw_name) == 0) {
+ array_pushback (grouplist, &groupentry->gr_gid);
+ }
+ }
+ }
+ endgrent ();
+
+ rval = setgroups (array_getlen (grouplist), array_data (grouplist));
+
+ errno_saved = errno;
+ array_free (grouplist);
+ errno = errno_saved;
+#endif
+
+ if (rval < 0) {
+ write (RAS_CONN (session)->fd, sufail_msg, sufail_len);
+ ras_session_log (session,
+ "cannot set supplementary groups: %s", strerror (errno));
+ return -1;
+ }
+
+ rval = setgid (login_user->pw_gid);
+ if (rval < 0) {
+ write (RAS_CONN (session)->fd, sufail_msg, sufail_len);
+ ras_session_log (session,
+ "cannot set primary group to %d: %s",
+ login_user->pw_gid, strerror (errno));
+ return -1;
+ }
+
+ rval = setuid (login_user->pw_uid);
+ if (rval < 0) {
+ write (RAS_CONN (session)->fd, sufail_msg, sufail_len);
+ ras_session_log (session,
+ "cannot set user to %s (uid = %d): %s",
+ login_user->pw_name, login_user->pw_uid, strerror (errno));
+ return -1;
+ }
+ }
+
return 0;
}