extern List as_mysql_get_accts(mysql_conn_t *mysql_conn, uid_t uid, slurmdb_account_cond_t *acct_cond) { char *query = NULL; char *extra = NULL; char *tmp = NULL; List acct_list = NULL; ListIterator itr = NULL; char *object = NULL; int set = 0; int i=0, is_admin=1; MYSQL_RES *result = NULL; MYSQL_ROW row; uint16_t private_data = 0; slurmdb_user_rec_t user; /* if this changes you will need to edit the corresponding enum */ char *acct_req_inx[] = { "name", "description", "organization" }; enum { SLURMDB_REQ_NAME, SLURMDB_REQ_DESC, SLURMDB_REQ_ORG, SLURMDB_REQ_COUNT }; if (check_connection(mysql_conn) != SLURM_SUCCESS) return NULL; memset(&user, 0, sizeof(slurmdb_user_rec_t)); user.uid = uid; private_data = slurm_get_private_data(); if (private_data & PRIVATE_DATA_ACCOUNTS) { if (!(is_admin = is_user_min_admin_level( mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) { if (!is_user_any_coord(mysql_conn, &user)) { error("Only admins/coordinators " "can look at account usage"); errno = ESLURM_ACCESS_DENIED; return NULL; } } } if (!acct_cond) { xstrcat(extra, "where deleted=0"); goto empty; } if (acct_cond->with_deleted) xstrcat(extra, "where (deleted=0 || deleted=1)"); else xstrcat(extra, "where deleted=0"); if (acct_cond->assoc_cond && acct_cond->assoc_cond->acct_list && list_count(acct_cond->assoc_cond->acct_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(acct_cond->assoc_cond->acct_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "name='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (acct_cond->description_list && list_count(acct_cond->description_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(acct_cond->description_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "description='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (acct_cond->organization_list && list_count(acct_cond->organization_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(acct_cond->organization_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "organization='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } empty: xfree(tmp); xstrfmtcat(tmp, "%s", acct_req_inx[i]); for(i=1; i<SLURMDB_REQ_COUNT; i++) { xstrfmtcat(tmp, ", %s", acct_req_inx[i]); } /* This is here to make sure we are looking at only this user * if this flag is set. We also include any accounts they may be * coordinator of. */ if (!is_admin && (private_data & PRIVATE_DATA_ACCOUNTS)) { slurmdb_coord_rec_t *coord = NULL; set = 0; itr = list_iterator_create(user.coord_accts); while ((coord = list_next(itr))) { if (set) { xstrfmtcat(extra, " || name='%s'", coord->name); } else { set = 1; xstrfmtcat(extra, " && (name='%s'", coord->name); } } list_iterator_destroy(itr); if (set) xstrcat(extra,")"); } query = xstrdup_printf("select %s from %s %s", tmp, acct_table, extra); xfree(tmp); xfree(extra); if (debug_flags & DEBUG_FLAG_DB_ASSOC) DB_DEBUG(mysql_conn->conn, "query\n%s", query); if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); return NULL; } xfree(query); acct_list = list_create(slurmdb_destroy_account_rec); if (acct_cond && acct_cond->assoc_cond && acct_cond->with_assocs) { /* We are going to be freeing the inners of this list in the acct->name so we don't free it here */ if (acct_cond->assoc_cond->acct_list) list_destroy(acct_cond->assoc_cond->acct_list); acct_cond->assoc_cond->acct_list = list_create(NULL); acct_cond->assoc_cond->with_deleted = acct_cond->with_deleted; } while ((row = mysql_fetch_row(result))) { slurmdb_account_rec_t *acct = xmalloc(sizeof(slurmdb_account_rec_t)); list_append(acct_list, acct); acct->name = xstrdup(row[SLURMDB_REQ_NAME]); acct->description = xstrdup(row[SLURMDB_REQ_DESC]); acct->organization = xstrdup(row[SLURMDB_REQ_ORG]); if (acct_cond && acct_cond->with_coords) { _get_account_coords(mysql_conn, acct); } if (acct_cond && acct_cond->with_assocs) { if (!acct_cond->assoc_cond) { acct_cond->assoc_cond = xmalloc( sizeof(slurmdb_association_cond_t)); } list_append(acct_cond->assoc_cond->acct_list, acct->name); } } mysql_free_result(result); if (acct_cond && acct_cond->with_assocs && acct_cond->assoc_cond && list_count(acct_cond->assoc_cond->acct_list)) { ListIterator assoc_itr = NULL; slurmdb_account_rec_t *acct = NULL; slurmdb_association_rec_t *assoc = NULL; List assoc_list = as_mysql_get_assocs( mysql_conn, uid, acct_cond->assoc_cond); if (!assoc_list) { error("no associations"); return acct_list; } itr = list_iterator_create(acct_list); assoc_itr = list_iterator_create(assoc_list); while ((acct = list_next(itr))) { while ((assoc = list_next(assoc_itr))) { if (strcmp(assoc->acct, acct->name)) continue; if (!acct->assoc_list) acct->assoc_list = list_create( slurmdb_destroy_association_rec); list_append(acct->assoc_list, assoc); list_remove(assoc_itr); } list_iterator_reset(assoc_itr); if (!acct->assoc_list) list_remove(itr); } list_iterator_destroy(itr); list_iterator_destroy(assoc_itr); list_destroy(assoc_list); } return acct_list; }
/* * as_pg_get_accts - get accounts * * IN pg_conn: database connection * IN uid: user performing the get operation * IN acct_cond: accounts to get * RET: list of accounts */ extern List as_pg_get_accts(pgsql_conn_t *pg_conn, uid_t uid, slurmdb_account_cond_t *acct_cond) { DEF_VARS; char *cond = NULL; List acct_list = NULL; ListIterator itr = NULL; int set=0, is_admin=1; slurmdb_user_rec_t user; /* no need to free lists */ char *ga_fields = "name, description, organization"; enum { F_NAME, F_DESC, F_ORG, F_COUNT }; if (check_db_connection(pg_conn) != SLURM_SUCCESS) return NULL; if (check_user_op(pg_conn, uid, PRIVATE_DATA_ACCOUNTS, &is_admin, &user) != SLURM_SUCCESS) { error("as/pg: user(%u) not found in db", uid); errno = ESLURM_USER_ID_MISSING; return NULL; } if (!is_admin && ! is_user_any_coord(pg_conn, &user)) { errno = ESLURM_ACCESS_DENIED; return NULL; } if(!acct_cond) { xstrcat(cond, "WHERE deleted=0"); goto empty; } if(acct_cond->with_deleted) xstrcat(cond, "WHERE (deleted=0 OR deleted=1)"); else xstrcat(cond, "WHERE deleted=0"); if(acct_cond->assoc_cond) concat_cond_list(acct_cond->assoc_cond->acct_list, NULL, "name", &cond); concat_cond_list(acct_cond->description_list, NULL, "description", &cond); concat_cond_list(acct_cond->organization_list, NULL, "organization", &cond); empty: if(!is_admin) { slurmdb_coord_rec_t *coord = NULL; set = 0; itr = list_iterator_create(user.coord_accts); while((coord = list_next(itr))) { if(set) { xstrfmtcat(cond, " OR name='%s'", coord->name); } else { set = 1; xstrfmtcat(cond, " AND (name='%s'", coord->name); } } list_iterator_destroy(itr); if(set) xstrcat(cond,")"); } query = xstrdup_printf("SELECT %s FROM %s %s", ga_fields, acct_table, cond); xfree(cond); result = DEF_QUERY_RET; if (!result) return NULL; acct_list = list_create(slurmdb_destroy_account_rec); if(acct_cond && acct_cond->with_assocs) { if(!acct_cond->assoc_cond) acct_cond->assoc_cond = xmalloc( sizeof(slurmdb_association_cond_t)); else if(acct_cond->assoc_cond->acct_list) list_destroy(acct_cond->assoc_cond->acct_list); acct_cond->assoc_cond->acct_list = list_create(NULL); } FOR_EACH_ROW { slurmdb_account_rec_t *acct = xmalloc(sizeof(slurmdb_account_rec_t)); list_append(acct_list, acct); acct->name = xstrdup(ROW(F_NAME)); acct->description = xstrdup(ROW(F_DESC)); acct->organization = xstrdup(ROW(F_ORG)); if(acct_cond && acct_cond->with_coords) _get_account_coords(pg_conn, acct); if(acct_cond && acct_cond->with_assocs) { list_append(acct_cond->assoc_cond->acct_list, acct->name); } } END_EACH_ROW; PQclear(result); /* get associations */ if(acct_cond && acct_cond->with_assocs && list_count(acct_cond->assoc_cond->acct_list)) { ListIterator assoc_itr = NULL; slurmdb_account_rec_t *acct = NULL; slurmdb_association_rec_t *assoc = NULL; List assoc_list = acct_storage_p_get_associations( pg_conn, uid, acct_cond->assoc_cond); if(!assoc_list) { error("as/pg: get_accounts: no associations"); return acct_list; } itr = list_iterator_create(acct_list); assoc_itr = list_iterator_create(assoc_list); while((acct = list_next(itr))) { while((assoc = list_next(assoc_itr))) { if(strcmp(assoc->acct, acct->name)) continue; if(!acct->assoc_list) acct->assoc_list = list_create( slurmdb_destroy_association_rec); list_append(acct->assoc_list, assoc); list_remove(assoc_itr); } list_iterator_reset(assoc_itr); if(!acct->assoc_list) /* problem acct */ list_remove(itr); } list_iterator_destroy(itr); list_iterator_destroy(assoc_itr); list_destroy(assoc_list); } return acct_list; }