Ejemplo n.º 1
0
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;
}