/* * smb_getfqdomainname * * In the system is in domain mode, the dns_domain property value * is returned. Otherwise, it returns the local domain obtained via * resolver. * * Returns 0 upon success. Otherwise, returns -1. */ int smb_getfqdomainname(char *buf, size_t buflen) { struct __res_state res_state; int rc; if (buf == NULL || buflen == 0) return (-1); *buf = '\0'; if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) { rc = smb_config_getstr(SMB_CI_DOMAIN_FQDN, buf, buflen); if ((rc != SMBD_SMF_OK) || (*buf == '\0')) return (-1); } else { bzero(&res_state, sizeof (struct __res_state)); if (res_ninit(&res_state)) return (-1); if (*res_state.defdname == '\0') { res_ndestroy(&res_state); return (-1); } (void) strlcpy(buf, res_state.defdname, buflen); res_ndestroy(&res_state); rc = 0; } return (rc); }
/* * smb_getdomainname * * Returns NETBIOS name of the domain if the system is in domain * mode. Or returns workgroup name if the system is in workgroup * mode. */ int smb_getdomainname(char *buf, size_t buflen) { int rc; if (buf == NULL || buflen == 0) return (-1); *buf = '\0'; rc = smb_config_getstr(SMB_CI_DOMAIN_NAME, buf, buflen); if ((rc != SMBD_SMF_OK) || (*buf == '\0')) return (-1); return (0); }
/* * smb_encode_netbios_name * * Set up the name and scope fields in the destination name_entry structure. * The name is padded with spaces to 15 bytes. The suffix is copied into the * last byte, i.e. "netbiosname <suffix>". The scope is copied and folded * to uppercase. */ void smb_encode_netbios_name(unsigned char *name, char suffix, unsigned char *scope, struct name_entry *dest) { smb_tonetbiosname((char *)name, (char *)dest->name, suffix); if (scope) { (void) strlcpy((char *)dest->scope, (const char *)scope, sizeof (dest->scope)); } else { (void) smb_config_getstr(SMB_CI_NBSCOPE, (char *)dest->scope, sizeof (dest->scope)); } (void) smb_strupr((char *)dest->scope); }
/*ARGSUSED*/ static int smbadm_list(int argc, char **argv) { char domain[MAXHOSTNAMELEN]; char fqdn[MAXHOSTNAMELEN]; char srvname[MAXHOSTNAMELEN]; char modename[16]; int rc; smb_inaddr_t srvipaddr; char ipstr[INET6_ADDRSTRLEN]; rc = smb_config_getstr(SMB_CI_SECURITY, modename, sizeof (modename)); if (rc != SMBD_SMF_OK) { (void) fprintf(stderr, gettext("cannot determine the operational mode\n")); return (1); } if (smb_getdomainname(domain, sizeof (domain)) != 0) { (void) fprintf(stderr, gettext("failed to get the %s name\n"), modename); return (1); } if (strcmp(modename, "workgroup") == 0) { (void) printf(gettext("[*] [%s]\n"), domain); return (0); } (void) printf(gettext("[*] [%s]\n"), domain); if ((smb_getfqdomainname(fqdn, sizeof (fqdn)) == 0) && (*fqdn != '\0')) (void) printf(gettext("[*] [%s]\n"), fqdn); if ((smb_get_dcinfo(srvname, MAXHOSTNAMELEN, &srvipaddr) == NT_STATUS_SUCCESS) && (*srvname != '\0') && (!smb_inet_iszero(&srvipaddr))) { (void) smb_inet_ntop(&srvipaddr, ipstr, SMB_IPSTRLEN(srvipaddr.a_family)); (void) printf(gettext("\t[+%s.%s] [%s]\n"), srvname, fqdn, ipstr); } smb_domain_show(); return (0); }
static int smb_get_machine_passwd(uint8_t *buf, size_t buflen) { char pwd[SMB_PASSWD_MAXLEN + 1]; int rc; if (buflen < SMBAUTH_HASH_SZ) return (-1); rc = smb_config_getstr(SMB_CI_MACHINE_PASSWD, pwd, sizeof (pwd)); if ((rc != SMBD_SMF_OK) || *pwd == '\0') return (-1); if (smb_auth_ntlm_hash(pwd, buf) != 0) return (-1); return (rc); }
/* * 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); }
/* * smb_nic_list_create * * Creates a NIC list either based on /var/smb/smbhosts.db or * by getting the information from OS. * * Note that the caller of this function should grab the * list lock. */ static int smb_nic_list_create(void) { smb_hosts_t hlist; smb_hostifs_t *iflist; smb_nic_t *nc; char *ifname; char excludestr[SMB_NIC_MAXEXCLLIST_LEN]; char *exclude[SMB_PI_MAX_NETWORKS]; int nexclude = 0; int i, rc; if ((rc = smb_nic_hlist_create(&hlist)) != SMB_NIC_SUCCESS) return (rc); smb_niclist.nl_cnt = 0; smb_niclist.nl_seqnum = random(); smb_niclist.nl_hcnt = hlist.h_num; smb_niclist.nl_nics = calloc(hlist.h_ifnum, sizeof (smb_nic_t)); if (smb_niclist.nl_nics == NULL) { smb_nic_hlist_destroy(&hlist); return (SMB_NIC_NO_MEMORY); } *excludestr = '\0'; (void) smb_config_getstr(SMB_CI_WINS_EXCL, excludestr, sizeof (excludestr)); nexclude = smb_nic_nbt_get_exclude_list(excludestr, exclude, SMB_PI_MAX_NETWORKS); nc = smb_niclist.nl_nics; iflist = list_head(&hlist.h_list); do { for (i = 0; i < iflist->if_num; i++) { ifname = iflist->if_names[i]; if (smb_nic_getinfo(ifname, nc, AF_INET) != SMB_NIC_SUCCESS) { if (smb_nic_getinfo(ifname, nc, AF_INET6) != SMB_NIC_SUCCESS) { continue; } } (void) strlcpy(nc->nic_host, iflist->if_host, sizeof (nc->nic_host)); (void) strlcpy(nc->nic_cmnt, iflist->if_cmnt, sizeof (nc->nic_cmnt)); smb_tonetbiosname(nc->nic_host, nc->nic_nbname, 0x00); if (strchr(ifname, ':')) nc->nic_smbflags |= SMB_NICF_ALIAS; if (smb_nic_nbt_exclude(nc, (const char **)exclude, nexclude)) nc->nic_smbflags |= SMB_NICF_NBEXCL; smb_niclist.nl_cnt++; nc++; } } while ((iflist = list_next(&hlist.h_list, iflist)) != NULL); smb_nic_hlist_destroy(&hlist); return (SMB_NIC_SUCCESS); }
/* * Some older clients (Windows 98) only handle the low byte * of the max workers value. If the low byte is less than * SMB_PI_MAX_WORKERS_MIN set it to SMB_PI_MAX_WORKERS_MIN. */ void smb_load_kconfig(smb_kmod_cfg_t *kcfg) { struct utsname uts; int64_t citem; int rc; bzero(kcfg, sizeof (smb_kmod_cfg_t)); (void) smb_config_getnum(SMB_CI_MAX_WORKERS, &citem); kcfg->skc_maxworkers = (uint32_t)citem; if ((kcfg->skc_maxworkers & 0xFF) < SMB_PI_MAX_WORKERS_MIN) { kcfg->skc_maxworkers &= ~0xFF; kcfg->skc_maxworkers += SMB_PI_MAX_WORKERS_MIN; } (void) smb_config_getnum(SMB_CI_KEEPALIVE, &citem); kcfg->skc_keepalive = (uint32_t)citem; if ((kcfg->skc_keepalive != 0) && (kcfg->skc_keepalive < SMB_PI_KEEP_ALIVE_MIN)) kcfg->skc_keepalive = SMB_PI_KEEP_ALIVE_MIN; (void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &citem); kcfg->skc_maxconnections = (uint32_t)citem; kcfg->skc_restrict_anon = smb_config_getbool(SMB_CI_RESTRICT_ANON); kcfg->skc_signing_enable = smb_config_getbool(SMB_CI_SIGNING_ENABLE); kcfg->skc_signing_required = smb_config_getbool(SMB_CI_SIGNING_REQD); kcfg->skc_netbios_enable = smb_config_getbool(SMB_CI_NETBIOS_ENABLE); kcfg->skc_ipv6_enable = smb_config_getbool(SMB_CI_IPV6_ENABLE); kcfg->skc_print_enable = smb_config_getbool(SMB_CI_PRINT_ENABLE); kcfg->skc_oplock_enable = smb_config_getbool(SMB_CI_OPLOCK_ENABLE); kcfg->skc_sync_enable = smb_config_getbool(SMB_CI_SYNC_ENABLE); kcfg->skc_traverse_mounts = smb_config_getbool(SMB_CI_TRAVERSE_MOUNTS); kcfg->skc_max_protocol = smb_config_get_max_protocol(); kcfg->skc_secmode = smb_config_get_secmode(); rc = smb_config_getnum(SMB_CI_MAXIMUM_CREDITS, &citem); if (rc != SMBD_SMF_OK) citem = SMB_PI_MAX_CREDITS; if (citem < SMB_PI_MIN_CREDITS) citem = SMB_PI_MIN_CREDITS; if (citem > SMB_PI_MAX_CREDITS) citem = SMB_PI_MAX_CREDITS; kcfg->skc_maximum_credits = (uint16_t)citem; rc = smb_config_getnum(SMB_CI_INITIAL_CREDITS, &citem); if (rc != SMBD_SMF_OK) citem = SMB_PI_MIN_CREDITS; if (citem < SMB_PI_MIN_CREDITS) citem = SMB_PI_MIN_CREDITS; if (citem > kcfg->skc_maximum_credits) citem = kcfg->skc_maximum_credits; kcfg->skc_initial_credits = (uint16_t)citem; (void) smb_getdomainname(kcfg->skc_nbdomain, sizeof (kcfg->skc_nbdomain)); (void) smb_getfqdomainname(kcfg->skc_fqdn, sizeof (kcfg->skc_fqdn)); (void) smb_getnetbiosname(kcfg->skc_hostname, sizeof (kcfg->skc_hostname)); (void) smb_config_getstr(SMB_CI_SYS_CMNT, kcfg->skc_system_comment, sizeof (kcfg->skc_system_comment)); smb_config_get_version(&kcfg->skc_version); kcfg->skc_execflags = smb_config_get_execinfo(NULL, NULL, 0); if (smb_config_get_localuuid(kcfg->skc_machine_uuid) < 0) { syslog(LOG_ERR, "smb_load_kconfig: no machine_uuid"); uuid_generate_time(kcfg->skc_machine_uuid); } /* skc_negtok, skc_negtok_len: see smbd_authsvc.c */ (void) uname(&uts); (void) snprintf(kcfg->skc_native_os, sizeof (kcfg->skc_native_os), "%s %s %s", uts.sysname, uts.release, uts.version); (void) strlcpy(kcfg->skc_native_lm, "Native SMB service", sizeof (kcfg->skc_native_lm)); }