static int do_useradd(const char * const file, const PWInfo * const pwinfo_) { char *file2; FILE *fp2; PWInfo pwinfo = *pwinfo_; if (pwinfo.login == NULL || *(pwinfo.login) == 0) { fprintf(stderr, "Missing login\n"); return PW_ERROR_MISSING_LOGIN; } if (file == NULL) { fprintf(stderr, "Missing passwd file\n"); return PW_ERROR_MISSING_PASSWD_FILE; } #ifndef ACCEPT_ROOT_VIRTUAL_USERS if (pwinfo.uid <= (uid_t) 0 || pwinfo.gid <= (gid_t) 0) { fprintf(stderr, "You must give (non-root) uid and gid\n"); return PW_ERROR_USERADD_NOT_ROOT; } #endif if (pwinfo.home == NULL) { fprintf(stderr, "Missing home directory\n"); return PW_ERROR_USERADD_MISSING_HOME_DIR; } if (pwinfo.gecos == NULL) { if ((pwinfo.gecos = strdup("")) == NULL) { no_mem(); } } if ((pwinfo.pwd = do_get_passwd()) == NULL) { fprintf(stderr, "Error with entering password - aborting\n"); return PW_ERROR_ENTER_PASSWD_PW_ERROR; } { char *cleartext = pwinfo.pwd; pwinfo.pwd = best_crypt(cleartext); if (*cleartext != 0) { memset(cleartext, 0, strlen(cleartext)); } } if ((file2 = newpasswd_filename(file)) == NULL) { no_mem(); } if ((fp2 = create_newpasswd(file, file2, pwinfo.login, 1, 0)) == NULL) { fprintf(stderr, "Error.\n" "Check that [%s] doesn't already exist,\n" "and that [%s] can be written.\n", pwinfo.login, file2); free(file2); return PW_ERROR_USER_ALREADY_EXIST; } if (add_new_pw_line(fp2, &pwinfo) != 0) { fprintf(stderr, "Unable to append a line\n"); goto bye; } fflush(fp2); #ifdef HAVE_FILENO fsync(fileno(fp2)); #endif if (fclose(fp2) != 0) { perror("Unable to close the file"); goto bye2; } if (rename(file2, file) != 0) { perror("Unable to rename the file"); goto bye2; } free(file2); return 0; bye: fclose(fp2); bye2: unlink(file2); free(file2); return PW_ERROR_UNEXPECTED_ERROR; }
static int do_usermod(const char * const file, const PWInfo *pwinfo) { char *file2; FILE *fp2; PWInfo fetched_info; static char line[LINE_MAX]; if (pwinfo->login == NULL || *(pwinfo->login) == 0) { fprintf(stderr, "Missing login\n"); return PW_ERROR_MISSING_LOGIN; } if (file == NULL) { fprintf(stderr, "Missing passwd file\n"); return PW_ERROR_MISSING_PASSWD_FILE; } if (fetch_pw_account(file, &fetched_info, line, sizeof line, pwinfo->login) != 0) { fprintf(stderr, "Unable to fetch info about user [%s] in file [%s]\n", pwinfo->login, file); return PW_ERROR_UNABLE_TO_FETCH; } if (pwinfo->pwd != NULL) { char *cleartext = pwinfo->pwd; fetched_info.pwd = best_crypt(cleartext); if (*cleartext != 0) { memset((volatile void *) cleartext, 0, strlen(cleartext)); } } if (pwinfo->uid > (uid_t) 0) { fetched_info.uid = pwinfo->uid; } if (pwinfo->gid > (gid_t) 0) { fetched_info.gid = pwinfo->gid; } if (pwinfo->home != NULL) { fetched_info.home = pwinfo->home; } if (pwinfo->gecos != NULL) { fetched_info.gecos = pwinfo->gecos; } if (pwinfo->has_bw_dl != 0) { if (pwinfo->has_bw_dl < 0) { fetched_info.has_bw_dl = 0; } else { fetched_info.has_bw_dl = pwinfo->has_bw_dl; fetched_info.bw_dl = pwinfo->bw_dl; } } if (pwinfo->has_bw_ul != 0) { if (pwinfo->has_bw_ul < 0) { fetched_info.has_bw_ul = 0; } else { fetched_info.has_bw_ul = pwinfo->has_bw_ul; fetched_info.bw_ul = pwinfo->bw_ul; } } if (pwinfo->has_quota_files != 0) { if (pwinfo->has_quota_files < 0) { fetched_info.has_quota_files = 0; } else { fetched_info.has_quota_files = pwinfo->has_quota_files; fetched_info.quota_files = pwinfo->quota_files; } } if (pwinfo->has_quota_size != 0) { if (pwinfo->has_quota_size < 0) { fetched_info.has_quota_size = 0; } else { fetched_info.has_quota_size = pwinfo->has_quota_size; fetched_info.quota_size = pwinfo->quota_size; } } if (pwinfo->has_ul_ratio != 0) { if (pwinfo->has_ul_ratio < 0) { fetched_info.has_ul_ratio = 0; } else { fetched_info.has_ul_ratio = pwinfo->has_ul_ratio; fetched_info.ul_ratio = pwinfo->ul_ratio; } } if (pwinfo->has_dl_ratio != 0) { if (pwinfo->has_dl_ratio < 0) { fetched_info.has_dl_ratio = 0; } else { fetched_info.has_dl_ratio = pwinfo->has_dl_ratio; fetched_info.dl_ratio = pwinfo->dl_ratio; } } if (pwinfo->allow_local_ip != NULL) { fetched_info.allow_local_ip = pwinfo->allow_local_ip; } if (pwinfo->deny_local_ip != NULL) { fetched_info.deny_local_ip = pwinfo->deny_local_ip; } if (pwinfo->allow_client_ip != NULL) { fetched_info.allow_client_ip = pwinfo->allow_client_ip; } if (pwinfo->deny_client_ip != NULL) { fetched_info.deny_client_ip = pwinfo->deny_client_ip; } if (pwinfo->has_time != 0) { if (pwinfo->has_time < 0) { fetched_info.has_time = 0; } else { fetched_info.has_time = pwinfo->has_time; } fetched_info.time_begin = pwinfo->time_begin; fetched_info.time_end = pwinfo->time_end; } if (pwinfo->has_per_user_max != 0) { if (pwinfo->has_per_user_max < 0) { fetched_info.has_per_user_max = 0; } else { fetched_info.has_per_user_max = pwinfo->has_per_user_max; fetched_info.per_user_max = pwinfo->per_user_max; } } if ((file2 = newpasswd_filename(file)) == NULL) { no_mem(); } if ((fp2 = create_newpasswd(file, file2, pwinfo->login, 0, 1)) == NULL) { fprintf(stderr, "Error.\n" "Check that [%s] already exists,\n" "and that [%s] can be written.\n", pwinfo->login, file2); free(file2); return PW_ERROR_USER_ALREADY_EXIST; } if (add_new_pw_line(fp2, &fetched_info) != 0) { fprintf(stderr, "Unable to append a line\n"); goto bye; } fflush(fp2); #ifdef HAVE_FILENO fsync(fileno(fp2)); #endif if (fclose(fp2) != 0) { perror("Unable to close the file"); goto bye2; } if (rename(file2, file) != 0) { perror("Unable to rename the file"); goto bye2; } free(file2); return 0; bye: fclose(fp2); bye2: unlink(file2); free(file2); return PW_ERROR_UNEXPECTED_ERROR; }