static int spoolss_getservername(char *name, size_t namelen) { char hostname[MAXHOSTNAMELEN]; char ipstr[INET6_ADDRSTRLEN]; smb_inaddr_t ipaddr; struct hostent *h; const char *p; int error; if (smb_gethostname(hostname, MAXHOSTNAMELEN, 0) != 0) { smb_tracef("spoolss_s_GetPrinter: gethostname failed"); return (-1); } if ((h = smb_gethostbyname(hostname, &error)) == NULL) { smb_tracef("spoolss_s_GetPrinter: gethostbyname failed: %d", error); return (-1); } bcopy(h->h_addr, &ipaddr, h->h_length); ipaddr.a_family = h->h_addrtype; freehostent(h); p = smb_inet_ntop(&ipaddr, ipstr, SMB_IPSTRLEN(ipaddr.a_family)); if (p == NULL) { smb_tracef("spoolss_s_GetPrinter: inet_ntop failed"); return (-1); } (void) snprintf(name, namelen, "\\\\%s", ipstr); return (0); }
/* * Obtain the fully-qualified name for this machine in lower case. If * the hostname is fully-qualified, accept it. Otherwise, try to find an * appropriate domain name to append to the hostname. */ int smb_getfqhostname(char *buf, size_t buflen) { char hostname[MAXHOSTNAMELEN]; char domain[MAXHOSTNAMELEN]; hostname[0] = '\0'; domain[0] = '\0'; if (smb_gethostname(hostname, MAXHOSTNAMELEN, SMB_CASE_LOWER) != 0) return (-1); if (smb_getfqdomainname(domain, MAXHOSTNAMELEN) != 0) return (-1); if (hostname[0] == '\0') return (-1); if (domain[0] == '\0') { (void) strlcpy(buf, hostname, buflen); return (0); } (void) snprintf(buf, buflen, "%s.%s", hostname, domain); return (0); }
/* * Doing "Unsecure join" (using a pre-created machine account). * All we need to do is change the password from the default * to a random string. * * Note: this is a work in progres. Nexenta issue 11960 * (allow joining an AD domain using a pre-created computer account) * It turns out that to change the machine account password, * we need to use a different RPC call, performed over the * NetLogon secure channel. (See netr_server_password_set2) */ static DWORD mlsvc_join_noauth(smb_domainex_t *dxi, char *machine_name, char *machine_pw) { char old_pw[SMB_SAMACCT_MAXLEN]; DWORD status; /* * Compose the current (default) password for the * pre-created machine account, which is just the * account name in lower case, truncated to 14 * characters. */ if (smb_gethostname(old_pw, sizeof (old_pw), SMB_CASE_LOWER) != 0) return (NT_STATUS_INTERNAL_ERROR); old_pw[14] = '\0'; status = netr_change_password(dxi->d_dci.dc_name, machine_name, old_pw, machine_pw); if (status != NT_STATUS_SUCCESS) { syslog(LOG_NOTICE, "Change machine account password: %s", xlate_nt_status(status)); } return (status); }
/* * Get the current system NetBIOS name. The hostname is truncated at * the first `.` or 15 bytes, whichever occurs first, and converted * to uppercase (by smb_gethostname). Text that appears after the * first '.' is considered to be part of the NetBIOS scope. * * Returns 0 on success, otherwise -1 to indicate an error. */ int smb_getnetbiosname(char *buf, size_t buflen) { if (smb_gethostname(buf, buflen, SMB_CASE_UPPER) != 0) return (-1); if (buflen >= NETBIOS_NAME_SZ) buf[NETBIOS_NAME_SZ - 1] = '\0'; return (0); }
/* * smb_nic_hlist_sysget * * Get the list of currently plumbed and up interface names. The loopback (lo0) * port is ignored */ static int smb_nic_hlist_sysget(smb_hosts_t *hlist) { smb_hostifs_t *iflist; struct lifconf lifc; struct lifreq lifrl; struct lifreq *lifrp; char *ifname; int ifnum; int i; int s4, s6; struct lifnum lifn; iflist = malloc(sizeof (smb_hostifs_t)); if (iflist == NULL) return (SMB_NIC_NO_MEMORY); bzero(iflist, sizeof (smb_hostifs_t)); if (smb_gethostname(iflist->if_host, sizeof (iflist->if_host), SMB_CASE_PRESERVE) < 0) { free(iflist); return (SMB_NIC_NO_HOST); } (void) smb_config_getstr(SMB_CI_SYS_CMNT, iflist->if_cmnt, sizeof (iflist->if_cmnt)); if ((s4 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { free(iflist); return (SMB_NIC_SOCK); } s6 = socket(AF_INET6, SOCK_DGRAM, 0); lifn.lifn_family = AF_UNSPEC; lifn.lifn_flags = 0; if (ioctl(s4, SIOCGLIFNUM, (char *)&lifn) < 0) { smb_close_sockets(s4, s6); free(iflist); syslog(LOG_ERR, "hlist_sysget: SIOCGLIFNUM errno=%d", errno); return (SMB_NIC_IOCTL); } lifc.lifc_len = lifn.lifn_count * sizeof (struct lifreq); lifc.lifc_buf = malloc(lifc.lifc_len); if (lifc.lifc_buf == NULL) { smb_close_sockets(s4, s6); free(iflist); return (SMB_NIC_NO_MEMORY); } bzero(lifc.lifc_buf, lifc.lifc_len); lifc.lifc_family = AF_UNSPEC; lifc.lifc_flags = 0; if (ioctl(s4, SIOCGLIFCONF, (char *)&lifc) < 0) { smb_close_sockets(s4, s6); free(iflist); free(lifc.lifc_buf); return (SMB_NIC_IOCTL); } lifrp = lifc.lifc_req; ifnum = lifc.lifc_len / sizeof (struct lifreq); hlist->h_num = 0; for (i = 0; i < ifnum; i++, lifrp++) { if ((iflist->if_num > 0) && smb_duplicate_nic(iflist, lifrp)) continue; /* * Get the flags so that we can skip the loopback interface */ (void) memset(&lifrl, 0, sizeof (lifrl)); (void) strlcpy(lifrl.lifr_name, lifrp->lifr_name, sizeof (lifrl.lifr_name)); if (ioctl(s4, SIOCGLIFFLAGS, (caddr_t)&lifrl) < 0) { if ((s6 < 0) || (ioctl(s6, SIOCGLIFFLAGS, (caddr_t)&lifrl) < 0)) { smb_close_sockets(s4, s6); free(lifc.lifc_buf); smb_nic_iflist_destroy(iflist); return (SMB_NIC_IOCTL); } } if (lifrl.lifr_flags & IFF_LOOPBACK) { continue; } if ((lifrl.lifr_flags & IFF_UP) == 0) { continue; } ifname = strdup(lifrp->lifr_name); if (ifname == NULL) { smb_close_sockets(s4, s6); free(lifc.lifc_buf); smb_nic_iflist_destroy(iflist); return (SMB_NIC_NO_MEMORY); } iflist->if_names[iflist->if_num++] = ifname; } hlist->h_ifnum = iflist->if_num; hlist->h_num = 1; smb_close_sockets(s4, s6); free(lifc.lifc_buf); list_insert_tail(&hlist->h_list, iflist); return (SMB_NIC_SUCCESS); }