/** * test1 default user * * Test that the username password admin/mariadb is accepted if no users * have been created and that no other users are accepted * * WARNING: The passwd file must be removed before this test is run */ static int test1() { if (admin_verify("admin", "mariadb") == 0) { fprintf(stderr, "admin_verify: test 1.1 (default user) failed.\n"); return 1; } if (admin_verify("bad", "user")) { fprintf(stderr, "admin_verify: test 1.2 (wrong user) failed.\n"); return 1; } return 0; }
/** * Remove maxscale user from in-memory structure and from password file * * @param uname Name of the new user * @param passwd Password for the new user * @return NULL on success or an error string on failure */ char* admin_remove_user( char* uname, char* passwd) { FILE* fp; FILE* fp_tmp; char fname[1024]; char fname_tmp[1024]; char* home; char fusr[LINELEN]; char fpwd[LINELEN]; char line[LINELEN]; fpos_t rpos; int n_deleted; if (!admin_search_user(uname)) { MXS_ERROR("Couldn't find user %s. Removing user failed.", uname); return ADMIN_ERR_USERNOTFOUND; } if (admin_verify(uname, passwd) == 0) { MXS_ERROR("Authentication failed, wrong user/password " "combination. Removing user failed."); return ADMIN_ERR_AUTHENTICATION; } /** Remove user from in-memory structure */ n_deleted = users_delete(users, uname); if (n_deleted == 0) { MXS_ERROR("Deleting the only user is forbidden. Add new " "user before deleting the one."); return ADMIN_ERR_DELLASTUSER; } /** * Open passwd file and remove user from the file. */ snprintf(fname, 1023, "%s/passwd", get_datadir()); snprintf(fname_tmp, 1023, "%s/passwd_tmp", get_datadir()); fname[1023] = '\0'; fname_tmp[1023] = '\0'; /** * Rewrite passwd file from memory. */ if ((fp = fopen(fname, "r")) == NULL) { int err = errno; MXS_ERROR("Unable to open password file %s : errno %d.\n" "Removing user from file failed; it must be done " "manually.", fname, err); return ADMIN_ERR_PWDFILEOPEN; } /** * Open temporary passwd file. */ if ((fp_tmp = fopen(fname_tmp, "w")) == NULL) { int err = errno; MXS_ERROR("Unable to open tmp file %s : errno %d.\n" "Removing user from passwd file failed; it must be done " "manually.", fname_tmp, err); fclose(fp); return ADMIN_ERR_TMPFILEOPEN; } /** * Scan passwd and copy all but matching lines to temp file. */ if (fgetpos(fp, &rpos) != 0) { int err = errno; MXS_ERROR("Unable to process passwd file %s : errno %d.\n" "Removing user from file failed, and must be done " "manually.", fname, err); fclose(fp); fclose(fp_tmp); unlink(fname_tmp); return ADMIN_ERR_PWDFILEACCESS; } while (fscanf(fp, "%[^:]:%s\n", fusr, fpwd) == 2) { /** * Compare username what was found from passwd file. * Unmatching lines are copied to tmp file. */ if (strncmp(uname, fusr, strlen(uname)+1) != 0) { if(fsetpos(fp, &rpos) != 0) { /** one step back */ MXS_ERROR("Unable to set stream position. "); } fgets(line, LINELEN, fp); fputs(line, fp_tmp); } if (fgetpos(fp, &rpos) != 0) { int err = errno; MXS_ERROR("Unable to process passwd file %s : " "errno %d.\n" "Removing user from file failed, and must be " "done manually.", fname, err); fclose(fp); fclose(fp_tmp); unlink(fname_tmp); return ADMIN_ERR_PWDFILEACCESS; } } fclose(fp); /** * Replace original passwd file with new. */ if (rename(fname_tmp, fname)) { int err = errno; MXS_ERROR("Unable to rename new passwd file %s : errno " "%d.\n" "Rename it to %s manually.", fname_tmp, err, fname); unlink(fname_tmp); fclose(fp_tmp); return ADMIN_ERR_PWDFILEACCESS; } fclose(fp_tmp); return ADMIN_SUCCESS; }
/** * Read event for EPOLLIN on the telnetd protocol module. * * @param dcb The descriptor control block * @return */ static int telnetd_read_event(DCB* dcb) { int n; GWBUF *head = NULL; SESSION *session = dcb->session; ROUTER_OBJECT *router = session->service->router; ROUTER *router_instance = session->service->router_instance; void *rsession = session->router_session; TELNETD *telnetd = (TELNETD *)dcb->protocol; char *password, *t; if ((n = dcb_read(dcb, &head)) != -1) { if (head) { unsigned char *ptr = GWBUF_DATA(head); ptr = GWBUF_DATA(head); while (GWBUF_LENGTH(head) && *ptr == TELNET_IAC) { telnetd_command(dcb, ptr + 1); GWBUF_CONSUME(head, 3); ptr = GWBUF_DATA(head); } if (GWBUF_LENGTH(head)) { switch (telnetd->state) { case TELNETD_STATE_LOGIN: telnetd->username = strndup(GWBUF_DATA(head), GWBUF_LENGTH(head)); /* Strip the cr/lf from the username */ t = strstr(telnetd->username, "\r\n"); if (t) *t = 0; telnetd->state = TELNETD_STATE_PASSWD; dcb_printf(dcb, "Password: "******"\r\n"); if (t) *t = 0; if (admin_verify(telnetd->username, password)) { telnetd_echo(dcb, 1); telnetd->state = TELNETD_STATE_DATA; dcb_printf(dcb, "\n\nMaxScale> "); } else { dcb_printf(dcb, "\n\rLogin incorrect\n\rLogin: "); telnetd_echo(dcb, 1); telnetd->state = TELNETD_STATE_LOGIN; free(telnetd->username); } gwbuf_consume(head, GWBUF_LENGTH(head)); free(password); break; case TELNETD_STATE_DATA: router->routeQuery(router_instance, rsession, head); break; } } else { // Force the free of the buffer header gwbuf_consume(head, 0); } } } return n; }
/** * test4 verify users * * Create a numebr of users * search for each user in turn * verify each user in turn (password verification) * Verify each user in turn with incorrect password * Randomly verify each user * Remove each user */ static int test4() { char *err, user[40], passwd[40]; int i, n_users = 50; for (i = 1; i < n_users; i++) { sprintf(user, "user%d", i); sprintf(passwd, "passwd%d", i); if ((err = admin_add_user(user, passwd)) != NULL) { fprintf(stderr, "admin_add_user: test 4.1 (add user) failed, %s.\n", err); return 1; } } for (i = 1; i < n_users; i++) { sprintf(user, "user%d", i); if (admin_search_user(user) == 0) { fprintf(stderr, "admin_search_user: test 4.2 (search user) failed.\n"); return 1; } } for (i = 1; i < n_users; i++) { sprintf(user, "user%d", i); sprintf(passwd, "passwd%d", i); if (admin_verify(user, passwd) == 0) { fprintf(stderr, "admin_verify: test 4.3 (search user) failed.\n"); return 1; } } for (i = 1; i < n_users; i++) { sprintf(user, "user%d", i); sprintf(passwd, "badpasswd%d", i); if (admin_verify(user, passwd) != 0) { fprintf(stderr, "admin_verify: test 4.4 (search user) failed.\n"); return 1; } } srand(time(0)); for (i = 1; i < 1000; i++) { int j; j = rand() % n_users; if (j == 0) j = 1; sprintf(user, "user%d", j); sprintf(passwd, "passwd%d", j); if (admin_verify(user, passwd) == 0) { fprintf(stderr, "admin_verify: test 4.5 (random) failed.\n"); return 1; } } for (i = 1; i < n_users; i++) { sprintf(user, "user%d", i); sprintf(passwd, "passwd%d", i); if ((err = admin_remove_user(user, passwd)) != NULL) { fprintf(stderr, "admin_remove_user: test 4.6 (add user) failed, %s.\n", err); return 1; } } return 0; }