/** * 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)) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Couldn't find user %s. Removing user failed", uname))); return ADMIN_ERR_USERNOTFOUND; } if (admin_verify(uname, passwd) == 0) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "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) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "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. */ sprintf(fname, "%s/passwd", get_datadir()); sprintf(fname_tmp, "%s/passwd_tmp", get_datadir()); /** * Rewrite passwd file from memory. */ if ((fp = fopen(fname, "r")) == NULL) { int err = errno; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "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; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "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; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "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 */ LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Unable to set stream position. "))); } fgets(line, LINELEN, fp); fputs(line, fp_tmp); } if (fgetpos(fp, &rpos) != 0) { int err = errno; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "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; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "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; }
static int gpsd_start( int unit, peerT * peer) { clockprocT * const pp = peer->procptr; gpsd_unitT * const up = emalloc_zero(sizeof(*up)); struct stat sb; /* initialize the unit structure */ up->fdt = -1; up->addr = s_gpsd_addr; up->tickpres = TICKOVER_LOW; /* setup refclock processing */ up->unit = unit; pp->unitptr = (caddr_t)up; pp->io.fd = -1; pp->io.clock_recv = gpsd_receive; pp->io.srcclock = peer; pp->io.datalen = 0; pp->a_lastcode[0] = '\0'; pp->lencode = 0; pp->clockdesc = DESCRIPTION; memcpy(&pp->refid, REFID, 4); /* Initialize miscellaneous variables */ peer->precision = PRECISION; /* Create the device name and check for a Character Device. It's * assumed that GPSD was started with the same link, so the * names match. (If this is not practicable, we will have to * read the symlink, if any, so we can get the true device * file.) */ if (-1 == myasprintf(&up->device, "%s%u", s_dev_stem, unit)) { msyslog(LOG_ERR, "%s clock device name too long", refnumtoa(&peer->srcadr)); goto dev_fail; } if (-1 == stat(up->device, &sb) || !S_ISCHR(sb.st_mode)) { msyslog(LOG_ERR, "%s: '%s' is not a character device", refnumtoa(&peer->srcadr), up->device); goto dev_fail; } LOGIF(CLOCKINFO, (LOG_NOTICE, "%s: startup, device is '%s'", refnumtoa(&peer->srcadr), up->device)); return TRUE; dev_fail: /* On failure, remove all UNIT ressources and declare defeat. */ INSIST (up); free(up->device); free(up); pp->unitptr = (caddr_t)NULL; return FALSE; }