/* Similar to semanage_direct_install(), except that it checks that * there already exists a module with the same name and that the * module is an older version then the one in 'data'. Returns 0 on * success, -1 if out of memory, -2 if the data does not represent a * valid module file, -3 if error while writing file or reading * modules directory, -4 if there does not exist an older module or if * the previous module is same or newer than 'data'. */ static int semanage_direct_upgrade(semanage_handle_t *sh, char *data, size_t data_len) { int i, retval, num_modules = 0; char *module_name = NULL, *version = NULL, *filename = NULL; semanage_module_info_t *modinfo = NULL; if ((retval = parse_module_headers(sh, data, data_len, &module_name, &version, &filename)) != 0) { goto cleanup; } if (semanage_direct_list(sh, &modinfo, &num_modules) < 0) { goto cleanup; } retval = -4; for (i = 0; i < num_modules; i++) { semanage_module_info_t *m = semanage_module_list_nth(modinfo, i); if (strcmp(semanage_module_get_name(m), module_name) == 0) { if (semanage_strverscmp(version, semanage_module_get_version(m)) > 0) { retval = 0; break; } else { ERR(sh, "Previous module %s is same or newer.", module_name); retval = -4; goto cleanup; } } } if (retval == -4) { ERR(sh, "There does not already exist a module named %s.", module_name); goto cleanup; } if (write_file(sh, filename, data, data_len) == -1) { retval = -3; } cleanup: free(version); free(filename); free(module_name); for (i = 0; modinfo != NULL && i < num_modules; i++) { semanage_module_info_t *m = semanage_module_list_nth(modinfo, i); semanage_module_info_datum_destroy(m); } free(modinfo); return retval; }
/* This function is used to preserve ABI compatibility with * versions of semodule using LIBSEMANAGE_1.0 */ int semanage_module_install_pp(semanage_handle_t * sh, char *module_data, size_t data_len) { char *name = NULL; char *version = NULL; int status; if ((status = parse_module_headers(sh, module_data, data_len, &name, &version)) != 0) { goto cleanup; } status = semanage_module_install_hll(sh, module_data, data_len, name, "pp"); cleanup: free(name); free(version); return status; }
/* Writes a module to the sandbox's module directory, overwriting any * previous module stored within. Note that module data are not * free()d by this function; caller is responsible for deallocating it * if necessary. Returns 0 on success, -1 if out of memory, -2 if the * data does not represent a valid module file, -3 if error while * writing file. */ static int semanage_direct_install(semanage_handle_t *sh, char *data, size_t data_len) { int retval; char *module_name = NULL, *version = NULL, *filename = NULL; if ((retval = parse_module_headers(sh, data, data_len, &module_name, &version, &filename)) != 0) { goto cleanup; } if (write_file(sh, filename, data, data_len) == -1) { retval = -3; } retval = 0; cleanup: free(version); free(filename); free(module_name); return retval; }