3 * @brief Implementation of Login related functionality
11 #define LDAP_DEPRECATED 1 // Required to use ldap_simple_bind_s
14 #define LDAP_URI "ldaps://ldap.pheme.uwa.edu.au"
15 #define LDAP_DN_BASE "ou=Users,ou=UWA,dc=uwads,dc=uwa,dc=edu,dc=au"
18 * Attempt to bind to the LDAP_URI
19 * @param user - The username
20 * @param pass - The password
21 * @returns An error code according to libldap; LDAP_SUCCESS if everything worked
23 int Login_LDAP_Bind(const char * user, const char * pass)
27 Log(LOGINFO, "Username: \"%s\"", user);
29 char dn[BUFSIZ]; // Fill with the DN
31 const char * user_type = "Students";
33 // Staff members have numbers starting in zero
39 if (sprintf(dn, "cn=%s,ou=%s,%s", user, user_type, LDAP_DN_BASE) >= BUFSIZ)
41 Log(LOGERR,"DN too long; recompile with increased BUFSIZ");
44 // Initialise LDAP; prepares to connect to the server
46 int err = ldap_initialize(&ld, LDAP_URI);
47 if (err != LDAP_SUCCESS || ld == NULL)
49 Log(LOGERR,"ldap_initialize failed - %s (ld = %p)", ldap_err2string(err), ld);
53 // Set the LDAP version...
54 int version = LDAP_VERSION3;
55 err = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version); // specify the version
56 if (err != LDAP_SUCCESS)
58 Log(LOGERR,"ldap_set_option failed - %s", ldap_err2string(err));
62 // Attempt to bind using the supplied credentials.
63 // NOTE: ldap_simple_bind_s is "deprecated" in <ldap.h>, but not listed as such in the man pages :S
64 err = ldap_simple_bind_s(ld, dn, pass);
65 if (err != LDAP_SUCCESS)
67 Log(LOGERR, "ldap_simple_bind_s failed - %s", ldap_err2string(err));
71 Log(LOGDEBUG, "Successfully bound to %s with username %s", LDAP_URI, user);
74 err = ldap_unbind_s(ld);
75 if (err != LDAP_SUCCESS)
77 Log(LOGERR, "ldap_unbind_s failed - %s", ldap_err2string(err));
84 * @param context - The context. The key will be cleared.
85 * @param params - Parameter string, UNUSED
87 void Logout_Handler(FCGIContext * context, char * params)
89 FCGI_ReleaseControl(context);
94 * Handle a Login Request
95 * @param context - The context
96 * @param params - Parameter string, should contain username and password
98 void Login_Handler(FCGIContext * context, char * params)
101 if (context->control_key[0] != '\0')
103 FCGI_RejectJSON(context, "Already logged in");
107 char * user = ""; // The username supplied through CGI
108 char * pass = ""; // The password supplied through CGI
109 //TODO: Make sure these are passed through HTTPS, *not* HTTP .... otherwise people can eavesdrop on the passwords
111 FCGIValue values[] = {
112 {"user", &user, FCGI_REQUIRED(FCGI_STRING_T)},
113 {"pass", &pass, FCGI_REQUIRED(FCGI_STRING_T)},
116 //enum to avoid the use of magic numbers
123 // Fill values appropriately
124 if (!FCGI_ParseRequest(context, params, values, sizeof(values)/sizeof(FCGIValue)))
126 // Error occured; FCGI_RejectJSON already called
131 // Trim leading whitespace (the BUFSIZ check is to make sure incorrectly terminated strings don't cause an infinite loop)
133 for (i = 0; i < BUFSIZ && isspace(user[0]) && user[0] != '\0'; ++i,++user);
135 // Truncate string at first non alphanumeric character
136 for (i = 0; i < BUFSIZ && isalnum(user[i]) && user[i] != '\0'; ++i);
139 if (strlen(pass) <= 0)
141 FCGI_RejectJSON(context, "No password supplied.");
145 // Try to authenticate
146 int err = Login_LDAP_Bind(user, pass);
150 if (err == LDAP_SUCCESS)
152 FCGI_LockControl(context, false);
156 FCGI_BeginJSON(context, STATUS_OK);
157 FCGI_JSONPair("user", user);
158 FCGI_JSONPair("login", ldap_err2string(err));
159 FCGI_JSONPair("key", context->control_key);