static Boolean __bond_remove_interface(int s, CFStringRef bond_if, CFStringRef interface_if) { struct if_bond_req breq; struct ifreq ifr; // bond interface bzero(&ifr, sizeof(ifr)); (void) _SC_cfstring_to_cstring(bond_if, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII); ifr.ifr_data = (caddr_t)&breq; // bond member to remove bzero(&breq, sizeof(breq)); breq.ibr_op = IF_BOND_OP_REMOVE_INTERFACE; (void) _SC_cfstring_to_cstring(interface_if, breq.ibr_ibru.ibru_if_name, sizeof(breq.ibr_ibru.ibru_if_name), kCFStringEncodingASCII); // remove bond member if (ioctl(s, SIOCSIFBOND, (caddr_t)&ifr) == -1) { _SCErrorSet(errno); SCLog(TRUE, LOG_ERR, CFSTR("could not remove interface \"%@\" from bond \"%@\": %s"), interface_if, bond_if, strerror(errno)); return FALSE; } return TRUE; }
static uid_t uid_from_odrecord(ODRecordRef record) { uid_t uid = -2; CFArrayRef values = NULL; values = ODRecordCopyValues(record, CFSTR(kDS1AttrUniqueID), NULL); if ((values != NULL) && (CFArrayGetCount(values) > 0)) { char buf[64]; char * end; CFStringRef uidStr; unsigned long val; uidStr = CFArrayGetValueAtIndex(values, 0); (void) _SC_cfstring_to_cstring(uidStr, buf, sizeof(buf), kCFStringEncodingASCII); errno = 0; val = strtoul(buf, &end, 0); if ((buf[0] != '\0') && (*end == '\0') && (errno == 0)) { uid = (uid_t)val; } } my_CFRelease(&values); return (uid); }
static Boolean __vlan_clear(int s, CFStringRef interface_if) { struct ifreq ifr; struct vlanreq vreq; bzero(&ifr, sizeof(ifr)); bzero(&vreq, sizeof(vreq)); // interface (void) _SC_cfstring_to_cstring(interface_if, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII); ifr.ifr_data = (caddr_t)&vreq; // clear physical interface bzero(&vreq.vlr_parent, sizeof(vreq.vlr_parent)); // clear tag vreq.vlr_tag = 0; // update physical interface and tag if (ioctl(s, SIOCSIFVLAN, (caddr_t)&ifr) == -1) { SCLog(TRUE, LOG_ERR, CFSTR("ioctl(SIOCSIFVLAN) failed: %s"), strerror(errno)); _SCErrorSet(kSCStatusFailed); return FALSE; } return TRUE; }
static Boolean __bond_set_mode(int s, CFStringRef bond_if, CFNumberRef mode) { struct if_bond_req breq; struct ifreq ifr; int mode_num; mode_num = IF_BOND_MODE_LACP; if (mode != NULL) { CFNumberGetValue(mode, kCFNumberIntType, &mode_num); } // bond interface bzero(&ifr, sizeof(ifr)); (void) _SC_cfstring_to_cstring(bond_if, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII); ifr.ifr_data = (caddr_t)&breq; bzero(&breq, sizeof(breq)); breq.ibr_op = IF_BOND_OP_SET_MODE; breq.ibr_ibru.ibru_int_val = mode_num; if (ioctl(s, SIOCSIFBOND, (caddr_t)&ifr) == -1) { _SCErrorSet(errno); SCLog(TRUE, LOG_ERR, CFSTR("could not set mode to %d on bond \"%@\": %s"), mode, bond_if, strerror(errno)); return FALSE; } return TRUE; }
char * AFPUser_get_user(AFPUserRef user, char *buf, size_t buf_len) { CFStringRef name; ODRecordRef record; record = (ODRecordRef)CFDictionaryGetValue(user, kAFPUserODRecord); name = ODRecordGetRecordName(record); (void) _SC_cfstring_to_cstring(name, buf, buf_len, kCFStringEncodingASCII); return buf; }
static Boolean __vlan_set(int s, CFStringRef interface_if, CFStringRef physical_if, CFNumberRef tag) { struct ifreq ifr; int tag_val; struct vlanreq vreq; bzero(&ifr, sizeof(ifr)); bzero(&vreq, sizeof(vreq)); // interface (void) _SC_cfstring_to_cstring(interface_if, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII); ifr.ifr_data = (caddr_t)&vreq; // physical interface (void) _SC_cfstring_to_cstring(physical_if, vreq.vlr_parent, sizeof(vreq.vlr_parent), kCFStringEncodingASCII); // tag CFNumberGetValue(tag, kCFNumberIntType, &tag_val); vreq.vlr_tag = tag_val; // update physical interface and tag if (ioctl(s, SIOCSIFVLAN, (caddr_t)&ifr) == -1) { SCLog(TRUE, LOG_ERR, CFSTR("ioctl(SIOCSIFVLAN) failed: %s"), strerror(errno)); _SCErrorSet(kSCStatusFailed); return FALSE; } return TRUE; }
/* * Function: AFPUser_set_random_password * Purpose: * Set a random password for the user and returns it in passwd. * Do not change the password again until AFPUSER_PASSWORD_CHANGE_INTERVAL * has elapsed. This overcomes the problem where every client * request packet is duplicated. In that case, the client tries to use * a password that subsequently gets changed when the duplicate arrives. */ Boolean AFPUser_set_random_password(AFPUserRef user, char * passwd, size_t passwd_len) { CFDateRef last_set; Boolean ok = TRUE; CFDateRef now; CFStringRef pw; ODRecordRef record; now = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent()); pw = CFDictionaryGetValue(user, kAFPUserPassword); last_set = CFDictionaryGetValue(user, kAFPUserDatePasswordLastSet); if (pw != NULL && last_set != NULL && (CFDateGetTimeIntervalSinceDate(now, last_set) < AFPUSER_PASSWORD_CHANGE_INTERVAL)) { /* return what we have */ #ifdef TEST_AFPUSERS printf("No need to change the password %d < %d\n", (int)CFDateGetTimeIntervalSinceDate(now, last_set), AFPUSER_PASSWORD_CHANGE_INTERVAL); #endif /* TEST_AFPUSERS */ (void)_SC_cfstring_to_cstring(pw, passwd, passwd_len, kCFStringEncodingASCII); CFDictionarySetValue(user, kAFPUserDatePasswordLastSet, now); } else { generate_random_password(passwd, passwd_len); record = (ODRecordRef)CFDictionaryGetValue(user, kAFPUserODRecord); pw = CFStringCreateWithCString(NULL, passwd, kCFStringEncodingASCII); ok = ODRecordChangePassword(record, NULL, pw, NULL); if (ok) { CFDictionarySetValue(user, kAFPUserPassword, pw); CFDictionarySetValue(user, kAFPUserDatePasswordLastSet, now); } else { my_log(LOG_NOTICE, "AFPUser_set_random_password:"******" ODRecordChangePassword() failed"); CFDictionaryRemoveValue(user, kAFPUserPassword); CFDictionaryRemoveValue(user, kAFPUserDatePasswordLastSet); } CFRelease(pw); } CFRelease(now); return ok; }
static Boolean ptr_query_start(CFStringRef address) { union { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; } addr; char buf[64]; CFDataRef data; CFMutableDictionaryRef options; if (_SC_cfstring_to_cstring(address, buf, sizeof(buf), kCFStringEncodingASCII) == NULL) { my_log(LOG_ERR, "could not convert [primary] address string"); return FALSE; } if (_SC_string_to_sockaddr(buf, AF_UNSPEC, (void *)&addr, sizeof(addr)) == NULL) { my_log(LOG_ERR, "could not convert [primary] address"); return FALSE; } options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); data = CFDataCreate(NULL, (const UInt8 *)&addr.sa, addr.sa.sa_len); CFDictionarySetValue(options, kSCNetworkReachabilityOptionPTRAddress, data); CFRelease(data); ptrTarget = SCNetworkReachabilityCreateWithOptions(NULL, options); CFRelease(options); if (ptrTarget == NULL) { my_log(LOG_ERR, "could not resolve [primary] address"); return FALSE; } my_log(LOG_INFO, "NetBIOS name: ptr query start"); (void) SCNetworkReachabilitySetCallback(ptrTarget, ptr_query_callback, NULL); (void) SCNetworkReachabilityScheduleWithRunLoop(ptrTarget, rl, kCFRunLoopDefaultMode); return TRUE; }
__private_extern__ Boolean __destroyInterface(int s, CFStringRef interface) { struct ifreq ifr; bzero(&ifr, sizeof(ifr)); (void) _SC_cfstring_to_cstring(interface, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII); if (ioctl(s, SIOCIFDESTROY, &ifr) == -1) { SCLog(TRUE, LOG_ERR, CFSTR("could not destroy interface \"%@\": %s"), interface, strerror(errno)); return FALSE; } return TRUE; }
static CFDictionaryRef copy_scoped_proxies(CFDictionaryRef services, CFArrayRef order) { CFIndex i; CFIndex n_order; CFMutableDictionaryRef scoped = NULL; // iterate over services n_order = isA_CFArray(order) ? CFArrayGetCount(order) : 0; for (i = 0; i < n_order; i++) { char if_name[IF_NAMESIZE]; CFStringRef interface; CFMutableDictionaryRef newProxy; CFDictionaryRef proxy; CFDictionaryRef service; CFStringRef serviceID; serviceID = CFArrayGetValueAtIndex(order, i); service = CFDictionaryGetValue(services, serviceID); if (!isA_CFDictionary(service)) { // if no service continue; } proxy = CFDictionaryGetValue(service, kSCEntNetProxies); if (!isA_CFDictionary(proxy)) { // if no proxy continue; } interface = CFDictionaryGetValue(proxy, kSCPropInterfaceName); if (interface == NULL) { // if no [scoped] interface continue; } if ((scoped != NULL) && CFDictionaryContainsKey(scoped, interface)) { // if we've already processed this [scoped] interface continue; } if ((_SC_cfstring_to_cstring(interface, if_name, sizeof(if_name), kCFStringEncodingASCII) == NULL) || ((if_nametoindex(if_name)) == 0)) { // if interface index not available continue; } // add [scoped] proxy entry // ... and remove keys we don't want in a [scoped] proxy CFRetain(interface); newProxy = CFDictionaryCreateMutableCopy(NULL, 0, proxy); CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplementalMatchDomains); CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplementalMatchOrders); CFDictionaryRemoveValue(newProxy, kSCPropInterfaceName); if (scoped == NULL) { scoped = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(scoped, interface, newProxy); CFRelease(newProxy); CFRelease(interface); } return scoped; }
static void booter(kickeeRef target) { char **argv = NULL; char *cmd = NULL; CFStringRef execCommand = CFDictionaryGetValue(target->dict, CFSTR("execCommand")); int i; CFArrayRef keys = NULL; CFStringRef name = CFDictionaryGetValue(target->dict, CFSTR("name")); int nKeys = 0; Boolean ok = FALSE; CFStringRef postName = CFDictionaryGetValue(target->dict, CFSTR("postName")); SCLog(_verbose, LOG_DEBUG, CFSTR("Kicker callback, target=%@"), name); if (!isA_CFString(postName) && !isA_CFString(execCommand)) { goto error; /* if no notifications to post nor commands to execute */ } if (isA_CFString(postName)) { uint32_t status; /* * post a notification */ cmd = _SC_cfstring_to_cstring(postName, NULL, 0, kCFStringEncodingASCII); if (!cmd) { SCLog(TRUE, LOG_DEBUG, CFSTR(" could not convert post name to C string")); goto error; } SCLog(TRUE, LOG_NOTICE, CFSTR("posting notification %s"), cmd); status = notify_post(cmd); if (status != NOTIFY_STATUS_OK) { SCLog(TRUE, LOG_DEBUG, CFSTR(" notify_post() failed: error=%ld"), status); goto error; } CFAllocatorDeallocate(NULL, cmd); /* clean up */ cmd = NULL; } /* * get the arguments for the kickee */ keys = target->changedKeys; target->changedKeys = NULL; if (isA_CFString(execCommand)) { CFRange bpr; CFNumberRef execGID = CFDictionaryGetValue(target->dict, CFSTR("execGID")); CFNumberRef execUID = CFDictionaryGetValue(target->dict, CFSTR("execUID")); CFBooleanRef passKeys = CFDictionaryGetValue(target->dict, CFSTR("changedKeysAsArguments")); gid_t reqGID = 0; uid_t reqUID = 0; CFMutableStringRef str; /* * build the kickee command */ str = CFStringCreateMutableCopy(NULL, 0, execCommand); bpr = CFStringFind(str, CFSTR("$BUNDLE"), 0); if (bpr.location != kCFNotFound) { CFStringRef bundlePath; bundlePath = CFURLCopyFileSystemPath(myBundleURL, kCFURLPOSIXPathStyle); CFStringReplace(str, bpr, bundlePath); CFRelease(bundlePath); } cmd = _SC_cfstring_to_cstring(str, NULL, 0, kCFStringEncodingASCII); CFRelease(str); if (!cmd) { SCLog(TRUE, LOG_DEBUG, CFSTR(" could not convert command to C string")); goto error; } /* * get the UID/GID for the kickee */ if (isA_CFNumber(execUID)) { CFNumberGetValue(execUID, kCFNumberIntType, &reqUID); } if (isA_CFNumber(execGID)) { CFNumberGetValue(execGID, kCFNumberIntType, &reqGID); } nKeys = CFArrayGetCount(keys); argv = CFAllocatorAllocate(NULL, (nKeys + 2) * sizeof(char *), 0); for (i = 0; i < (nKeys + 2); i++) { argv[i] = NULL; } /* create command name argument */ if ((argv[0] = rindex(cmd, '/')) != NULL) { argv[0]++; } else { argv[0] = cmd; } /* create changed key arguments */ if (isA_CFBoolean(passKeys) && CFBooleanGetValue(passKeys)) { for (i = 0; i < nKeys; i++) { CFStringRef key = CFArrayGetValueAtIndex(keys, i); argv[i+1] = _SC_cfstring_to_cstring(key, NULL, 0, kCFStringEncodingASCII); if (!argv[i+1]) { SCLog(TRUE, LOG_DEBUG, CFSTR(" could not convert argument to C string")); goto error; } } } SCLog(TRUE, LOG_NOTICE, CFSTR("executing %s"), cmd); SCLog(_verbose, LOG_DEBUG, CFSTR(" current uid = %d, requested = %d"), geteuid(), reqUID); /* this kicker is now "running" */ target->active = TRUE; (void)_SCDPluginExecCommand(booterExit, target, reqUID, reqGID, cmd, argv); // CFAllocatorDeallocate(NULL, cmd); /* clean up */ // cmd = NULL; } else { target->active = FALSE; } target->needsKick = FALSE; /* allow additional requests to be queued */ ok = TRUE; error : if (keys) CFRelease(keys); if (cmd) CFAllocatorDeallocate(NULL, cmd); if (argv) { for (i = 0; i < nKeys; i++) { if (argv[i+1]) { CFAllocatorDeallocate(NULL, argv[i+1]); } } CFAllocatorDeallocate(NULL, argv); } if (!ok) { /* * If the target action can't be performed this time then * there's not much point in trying again. As such, I close * the session and the kickee target released. */ cleanupKicker(target); } return; }
static void updateDefaults(const void *key, const void *val, void *context) { CFStringRef ifName = (CFStringRef)key; CFDictionaryRef oldDict; CFDictionaryRef newDict = (CFDictionaryRef)val; CFNumberRef defaultNode; CFNumberRef defaultNetwork; CFStringRef defaultZone; if (!CFDictionaryGetValueIfPresent(curDefaults, ifName, (const void **)&oldDict) || !CFEqual(oldDict, newDict)) { char ifr_name[IFNAMSIZ+1]; bzero(&ifr_name, sizeof(ifr_name)); if (!_SC_cfstring_to_cstring(ifName, ifr_name, sizeof(ifr_name), kCFStringEncodingASCII)) { SCLog(TRUE, LOG_ERR, CFSTR("could not convert interface name to C string")); return; } /* * Set preferred Network and Node ID */ if (CFDictionaryGetValueIfPresent(newDict, kSCPropNetAppleTalkNetworkID, (const void **)&defaultNetwork) && CFDictionaryGetValueIfPresent(newDict, kSCPropNetAppleTalkNodeID, (const void **)&defaultNode) ) { struct at_addr init_address; int status; /* * set the default node and network */ CFNumberGetValue(defaultNetwork, kCFNumberShortType, &init_address.s_net); CFNumberGetValue(defaultNode, kCFNumberCharType, &init_address.s_node); status = at_setdefaultaddr(ifr_name, &init_address); if (status == -1) { SCLog(TRUE, LOG_ERR, CFSTR("at_setdefaultaddr() failed")); return; } } /* * Set default zone */ if (CFDictionaryGetValueIfPresent(newDict, kSCPropNetAppleTalkDefaultZone, (const void **)&defaultZone) ) { int status; at_nvestr_t zone; /* * set the "default zone" for this interface */ bzero(&zone, sizeof(zone)); if (!_SC_cfstring_to_cstring(defaultZone, zone.str, sizeof(zone.str), kCFStringEncodingASCII)) { SCLog(TRUE, LOG_ERR, CFSTR("could not convert default zone to C string")); return; } zone.len = strlen(zone.str); status = at_setdefaultzone(ifr_name, &zone); if (status == -1) { SCLog(TRUE, LOG_ERR, CFSTR("at_setdefaultzone() failed")); return; } } } return; }
static void startAppleTalk(CFRunLoopTimerRef timer, void *info) { int argc = 0; char *argv[8]; char *computerName = NULL; char *interface = NULL; CFStringRef mode = CFDictionaryGetValue(curStartup, CFSTR("APPLETALK")); CFStringRef name = CFDictionaryGetValue(curStartup, CFSTR("APPLETALK_HOSTNAME")); SCLog(TRUE, LOG_NOTICE, CFSTR("AppleTalk startup")); if (!mode) { // Huh? return; } // set command name argv[argc++] = "appletalk"; // set hostname if (name) { computerName = _SC_cfstring_to_cstring(name, NULL, 0, kCFStringEncodingASCII); if (computerName) { argv[argc++] = "-C"; argv[argc++] = computerName; } else { // could not convert name goto done; } } // set mode if (CFEqual(mode, CFSTR("-ROUTER-"))) { argv[argc++] = "-r"; } else if (CFEqual(mode, CFSTR("-MULTIHOME-"))) { argv[argc++] = "-x"; } else { interface = _SC_cfstring_to_cstring(mode, NULL, 0, kCFStringEncodingASCII); if (interface) { argv[argc++] = "-u"; argv[argc++] = interface; } else { // could not convert interface goto done; } } // set non-interactive argv[argc++] = "-q"; // close argument list argv[argc++] = NULL; execCommand = _SCDPluginExecCommand(startComplete, // callback info, // context 0, // uid 0, // gid "/usr/sbin/appletalk", // path argv); // argv if (!timer) { execRetry = 5; // initialize retry count } done : if (computerName) CFAllocatorDeallocate(NULL, computerName); if (interface) CFAllocatorDeallocate(NULL, interface); return; }
SCBondStatusRef SCBondInterfaceCopyStatus(SCBondInterfaceRef bond) { int bond_if_active; int bond_if_status; CFIndex i; struct if_bond_status_req *ibsr_p = NULL; char if_name[IFNAMSIZ]; CFIndex n; CFNumberRef num; int s; struct if_bond_status *scan_p; SCBondStatusRef status = NULL; CFMutableDictionaryRef status_bond; CFMutableDictionaryRef status_interfaces; if (!isA_SCBondInterface(bond)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } s = inet_dgram_socket(); if (s == -1) { _SCErrorSet(errno); goto done; } _SC_cfstring_to_cstring(SCNetworkInterfaceGetBSDName(bond), if_name, sizeof(if_name), kCFStringEncodingASCII); if (siocgifmedia(s, if_name, &bond_if_status, &bond_if_active) == -1) { _SCErrorSet(errno); switch (errno) { case EBUSY : case ENXIO : break; default : SCLog(TRUE, LOG_ERR, CFSTR("siocgifmedia(%s) failed: %s"), if_name, strerror(errno)); } goto done; } ibsr_p = if_bond_status_req_copy(s, if_name); if (ibsr_p == NULL) { _SCErrorSet(errno); goto done; } status_bond = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); status_interfaces = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); n = ibsr_p->ibsr_total; for (i = 0, scan_p = (struct if_bond_status *)ibsr_p->ibsr_buffer; i < n; i++, scan_p++) { int collecting = 0; int distributing = 0; SCNetworkInterfaceRef interface; CFStringRef interface_name; struct if_bond_partner_state * ps; CFMutableDictionaryRef status_interface; int status_val; ps = &scan_p->ibs_partner_state; if (lacp_actor_partner_state_in_sync(scan_p->ibs_state)) { /* we're in-sync */ status_val = kSCBondStatusOK; if (lacp_actor_partner_state_in_sync(ps->ibps_state)) { /* partner is also in-sync */ if (lacp_actor_partner_state_collecting(scan_p->ibs_state) && lacp_actor_partner_state_distributing(ps->ibps_state)) { /* we're able to collect (receive) frames */ collecting = 1; } if (lacp_actor_partner_state_distributing(scan_p->ibs_state) && lacp_actor_partner_state_collecting(ps->ibps_state)) { /* we're able to distribute (transmit) frames */ distributing = 1; } } } else { int active = 0; int status = 0; static lacp_system zeroes = { {0, 0, 0, 0, 0, 0}}; if (siocgifmedia(s, scan_p->ibs_if_name, &status, &active) == -1) { switch (errno) { case EBUSY : case ENXIO : break; default : SCLog(TRUE, LOG_ERR, CFSTR("siocgifmedia(%s) failed: %s"), if_name, strerror(errno)); break; } } if (((status & IFM_AVALID) == 0) || ((status & IFM_ACTIVE) == 0) || ((active & IFM_FDX ) == 0)) { /* link down or not full-duplex */ status_val = kSCBondStatusLinkInvalid; } else if ((ps->ibps_system_priority == 0) && (bcmp(&zeroes, &ps->ibps_system, sizeof(zeroes)) == 0)) { /* no one on the other end of the link */ status_val = kSCBondStatusNoPartner; } else if (active != bond_if_active) { /* the link speed was different */ status_val = kSCBondStatusLinkInvalid; } else { /* partner is not in the active group */ status_val = kSCBondStatusNotInActiveGroup; } } // interface strlcpy(if_name, scan_p->ibs_if_name, sizeof(if_name)); interface_name = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingASCII); interface = _SCNetworkInterfaceCreateWithBSDName(NULL, interface_name, kIncludeNoVirtualInterfaces); CFRelease(interface_name); // interface status status_interface = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); num = CFNumberCreate(NULL, kCFNumberIntType, &status_val); CFDictionarySetValue(status_interface, kSCBondStatusDeviceAggregationStatus, num); CFRelease(num); num = CFNumberCreate(NULL, kCFNumberIntType, &collecting); CFDictionarySetValue(status_interface, kSCBondStatusDeviceCollecting, num); CFRelease(num); num = CFNumberCreate(NULL, kCFNumberIntType, &distributing); CFDictionarySetValue(status_interface, kSCBondStatusDeviceDistributing, num); CFRelease(num); CFDictionarySetValue(status_interfaces, interface, status_interface); CFRelease(interface); CFRelease(status_interface); } status = __SCBondStatusCreatePrivate(NULL, bond, status_bond, status_interfaces); CFRelease(status_bond); CFRelease(status_interfaces); done: if (s != -1) { close(s); } if (ibsr_p != NULL) { free(ibsr_p); } return (SCBondStatusRef)status; }