/* * Create a new indirect link * * An indirect link is a reference to a data node. The only useable * fields in the link are the link number, parentID, name and text * encoding. All other catalog fields are ignored. */ static int createindirectlink(struct hfsmount *hfsmp, u_int32_t linknum, u_int32_t linkparid, char *linkName, cnid_t *linkcnid) { struct FndrFileInfo *fip; struct cat_desc desc; struct cat_attr attr; int result; /* Setup the descriptor */ bzero(&desc, sizeof(desc)); desc.cd_nameptr = linkName; desc.cd_namelen = strlen(linkName); desc.cd_parentcnid = linkparid; /* Setup the default attributes */ bzero(&attr, sizeof(attr)); /* links are matched to data nodes by link ID and to volumes by create date */ attr.ca_rdev = linknum; /* note: cat backend overloads ca_rdev to be the linknum when nlink = 0 */ attr.ca_itime = HFSTOVCB(hfsmp)->vcbCrDate; attr.ca_mode = S_IFREG; fip = (struct FndrFileInfo *)&attr.ca_finderinfo; fip->fdType = SWAP_BE32 (kHardLinkFileType); /* 'hlnk' */ fip->fdCreator = SWAP_BE32 (kHFSPlusCreator); /* 'hfs+' */ fip->fdFlags = SWAP_BE16 (kHasBeenInited); hfs_global_shared_lock_acquire(hfsmp); if (hfsmp->jnl) { if (journal_start_transaction(hfsmp->jnl) != 0) { hfs_global_shared_lock_release(hfsmp); return EINVAL; } } /* Create the indirect link directly in the catalog */ result = cat_create(hfsmp, &desc, &attr, NULL); if (result == 0 && linkcnid != NULL) *linkcnid = attr.ca_fileid; if (hfsmp->jnl) { journal_end_transaction(hfsmp->jnl); } hfs_global_shared_lock_release(hfsmp); return (result); }
poldiff_t *poldiff_create(apol_policy_t * orig_policy, apol_policy_t * mod_policy, poldiff_handle_fn_t fn, void *callback_arg) { poldiff_t *diff = NULL; int error; if (!orig_policy || !mod_policy) { ERR(NULL, "%s", strerror(EINVAL)); errno = EINVAL; return NULL; } if (!(diff = calloc(1, sizeof(poldiff_t)))) { ERR(NULL, "%s", strerror(ENOMEM)); errno = ENOMEM; return NULL; } diff->orig_pol = orig_policy; diff->mod_pol = mod_policy; diff->orig_qpol = apol_policy_get_qpol(diff->orig_pol); diff->mod_qpol = apol_policy_get_qpol(diff->mod_pol); diff->fn = fn; diff->handle_arg = callback_arg; if ((diff->type_map = type_map_create()) == NULL) { ERR(diff, "%s", strerror(ENOMEM)); poldiff_destroy(&diff); errno = ENOMEM; return NULL; } if (type_map_infer(diff) < 0) { error = errno; poldiff_destroy(&diff); errno = error; return NULL; } if ((diff->attrib_diffs = attrib_summary_create()) == NULL || (diff->avrule_diffs[AVRULE_OFFSET_ALLOW] = avrule_create()) == NULL || (diff->avrule_diffs[AVRULE_OFFSET_AUDITALLOW] = avrule_create()) == NULL || (diff->avrule_diffs[AVRULE_OFFSET_DONTAUDIT] = avrule_create()) == NULL || (diff->avrule_diffs[AVRULE_OFFSET_NEVERALLOW] = avrule_create()) == NULL || (diff->bool_diffs = bool_create()) == NULL || (diff->cat_diffs = cat_create()) == NULL || (diff->class_diffs = class_create()) == NULL || (diff->common_diffs = common_create()) == NULL || (diff->level_diffs = level_create()) == NULL || (diff->range_trans_diffs = range_trans_create()) == NULL || (diff->role_diffs = role_create()) == NULL || (diff->role_allow_diffs = role_allow_create()) == NULL || (diff->role_trans_diffs = role_trans_create()) == NULL || (diff->terule_diffs[TERULE_OFFSET_CHANGE] = terule_create()) == NULL || (diff->terule_diffs[TERULE_OFFSET_MEMBER] = terule_create()) == NULL || (diff->terule_diffs[TERULE_OFFSET_TRANS] = terule_create()) == NULL || (diff->type_diffs = type_summary_create()) == NULL || (diff->user_diffs = user_create()) == NULL) { ERR(diff, "%s", strerror(ENOMEM)); poldiff_destroy(&diff); errno = ENOMEM; return NULL; } diff->policy_opts = QPOL_POLICY_OPTION_NO_RULES | QPOL_POLICY_OPTION_NO_NEVERALLOWS; return diff; }