Esempio n. 1
0
int
cmd_lookup(int argc, char *argv[])
{
    struct nb_ctx *ctx;
    struct sockaddr *sap;
    char *hostname;
    int error, opt;

    if (argc < 2)
        lookup_usage();
    error = nb_ctx_create(&ctx);
    if (error) {
        smb_error("unable to create nbcontext", error);
        exit(1);
    }
    if (smb_open_rcfile() == 0) {
        if (nb_ctx_readrcsection(smb_rc, ctx, "default", 0) != 0)
            exit(1);
        rc_close(smb_rc);
    }
    while ((opt = getopt(argc, argv, "w:")) != EOF) {
        switch(opt) {
        case 'w':
            nb_ctx_setns(ctx, optarg);
            break;
        default:
            lookup_usage();
            /*NOTREACHED*/
        }
    }
    if (optind >= argc)
        lookup_usage();
    if (nb_ctx_resolve(ctx) != 0)
        exit(1);
    hostname = argv[argc - 1];
    /*	printf("Looking for %s...\n", hostname);*/
    error = nbns_resolvename(hostname, ctx, &sap);
    if (error) {
        smb_error("unable to resolve %s", error, hostname);
        exit(1);
    }
    printf("Got response from %s\n", inet_ntoa(ctx->nb_lastns.sin_addr));
    printf("IP address of %s: %s\n", hostname, inet_ntoa(((struct sockaddr_in*)sap)->sin_addr));
    return 0;
}
Esempio n. 2
0
/*
 * Verify context before connect operation(s),
 * lookup specified server and try to fill all forgotten fields.
 */
int
smb_ctx_resolve(struct smb_ctx *ctx)
{
	struct smbioc_ossn *ssn = &ctx->ct_ssn;
	struct smbioc_oshare *sh = &ctx->ct_sh;
	struct nb_name nn;
	struct sockaddr *sap;
	struct sockaddr_nb *salocal, *saserver;
	char *cp;
	u_char cstbl[256];
	u_int i;
	int error = 0;
	
	ctx->ct_flags &= ~SMBCF_RESOLVED;
	if (ssn->ioc_srvname[0] == 0) {
		smb_error("no server name specified", 0);
		return EINVAL;
	}
	if (ssn->ioc_user[0] == 0) {
		smb_error("no user name specified for server %s",
		    0, ssn->ioc_srvname);
		return EINVAL;
	}
	if (ctx->ct_minlevel >= SMBL_SHARE && sh->ioc_share[0] == 0) {
		smb_error("no share name specified for %s@%s",
		    0, ssn->ioc_user, ssn->ioc_srvname);
		return EINVAL;
	}
	error = nb_ctx_resolve(ctx->ct_nb);
	if (error)
		return error;
	if (ssn->ioc_localcs[0] == 0)
		strcpy(ssn->ioc_localcs, "default");	/* XXX: locale name ? */
	error = smb_addiconvtbl("tolower", ssn->ioc_localcs, nls_lower);
	if (error)
		return error;
	error = smb_addiconvtbl("toupper", ssn->ioc_localcs, nls_upper);
	if (error)
		return error;
	if (ssn->ioc_servercs[0] != 0) {
		for(i = 0; i < sizeof(cstbl); i++)
			cstbl[i] = i;
		nls_mem_toext(cstbl, cstbl, sizeof(cstbl));
		error = smb_addiconvtbl(ssn->ioc_servercs, ssn->ioc_localcs, cstbl);
		if (error)
			return error;
		for(i = 0; i < sizeof(cstbl); i++)
			cstbl[i] = i;
		nls_mem_toloc(cstbl, cstbl, sizeof(cstbl));
		error = smb_addiconvtbl(ssn->ioc_localcs, ssn->ioc_servercs, cstbl);
		if (error)
			return error;
	}
	if (ctx->ct_srvaddr) {
		error = nb_resolvehost_in(ctx->ct_srvaddr, &sap);
	} else {
		error = nbns_resolvename(ssn->ioc_srvname, ctx->ct_nb, &sap);
	}
	if (error) {
		smb_error("can't get server address", error);
		return error;
	}
	nn.nn_scope = ctx->ct_nb->nb_scope;
	nn.nn_type = NBT_SERVER;
	strcpy(nn.nn_name, ssn->ioc_srvname);
	error = nb_sockaddr(sap, &nn, &saserver);
	nb_snbfree(sap);
	if (error) {
		smb_error("can't allocate server address", error);
		return error;
	}
	ssn->ioc_server = (struct sockaddr*)saserver;
	if (ctx->ct_locname[0] == 0) {
		error = nb_getlocalname(ctx->ct_locname);
		if (error) {
			smb_error("can't get local name", error);
			return error;
		}
		nls_str_upper(ctx->ct_locname, ctx->ct_locname);
	}
	strcpy(nn.nn_name, ctx->ct_locname);
	nn.nn_type = NBT_WKSTA;
	nn.nn_scope = ctx->ct_nb->nb_scope;
	error = nb_sockaddr(NULL, &nn, &salocal);
	if (error) {
		nb_snbfree((struct sockaddr*)saserver);
		smb_error("can't allocate local address", error);
		return error;
	}
	ssn->ioc_local = (struct sockaddr*)salocal;
	ssn->ioc_lolen = salocal->snb_len;
	ssn->ioc_svlen = saserver->snb_len;
	if (ssn->ioc_password[0] == 0 && (ctx->ct_flags & SMBCF_NOPWD) == 0) {
		cp = getpass("Password:");
		error = smb_ctx_setpassword(ctx, cp);
		if (error)
			return error;
	}
	ctx->ct_flags |= SMBCF_RESOLVED;
	return 0;
}
Esempio n. 3
0
/* Find all address associated with the NetBIOS name */
struct sockaddr_storage *
SMBResolveNetBIOSNameEx(const char *hostName, uint8_t nodeType,
                        const char *winServer, uint32_t timeout,
                        struct sockaddr_storage *respAddr, int32_t *outCount)
{
    struct sockaddr_storage *outAddr = NULL, *listAddr;
    char *netbios_name = NULL;
    struct nb_ctx ctx;
    CFMutableArrayRef addressArray = NULL;
    CFMutableDataRef addressData;
    struct connectAddress *conn;
    CFIndex ii;
    int error = 0;
    struct smb_prefs prefs;

    bzero(&ctx, sizeof(struct nb_ctx));
    /* Read the preference files */
    readPreferences(&prefs, NULL, NULL, FALSE, TRUE);

    /* They gave us a wins server use it */
    if (winServer) {
        setWINSAddress(&prefs, winServer, 1);
    }
    /* They gave us a timeout value use it */
    if ((int32_t)timeout > 0) {
        prefs.NetBIOSResolverTimeout = timeout;
    }

    /*
     * We uppercase and convert the server name given in the URL to Windows Code
     * Page.
     */
    netbios_name = convert_utf8_to_wincs(hostName, prefs.WinCodePage, TRUE);
    if (netbios_name == NULL) {
        error = ENOMEM;
        goto done;
    }
    /* Only returns IPv4 address */
    error = nbns_resolvename(&ctx, &prefs, netbios_name, nodeType, &addressArray,
                             SMB_TCP_PORT_445, TRUE, FALSE, NULL);
    if (error) {
        goto done;
    }

    if (respAddr) {
        memcpy(respAddr, &ctx.nb_sender, sizeof(ctx.nb_sender));
    }

    listAddr = outAddr = malloc(CFArrayGetCount(addressArray) * sizeof(struct sockaddr_storage));
    if (outAddr == NULL) {
        error = ENOMEM;
        goto done;
    }

    for (ii=0; ii < CFArrayGetCount(addressArray); ii++) {
        addressData = (CFMutableDataRef)CFArrayGetValueAtIndex(addressArray, ii);
        if (addressData) {
            conn = (struct connectAddress *)(void *)CFDataGetMutableBytePtr(addressData);
            if (conn) {
                *outCount += 1;
                *listAddr++ = conn->storage;
            }
        }
    }
    if (*outCount == 0) {
        free(outAddr);
        outAddr = NULL; /* Didn't really find any */
        error = EHOSTUNREACH;
    }
done:
    if (addressArray)
        CFRelease(addressArray);

    if (netbios_name) {
        free(netbios_name);
    }
    releasePreferenceInfo(&prefs);
    errno = error;
    return outAddr;
}
Esempio n. 4
0
/*
 * Call NetBIOS name lookup and return a result in the
 * same form as getaddrinfo(3) returns.  Return code is
 * zero or one of the EAI_xxx codes like getaddrinfo.
 */
int
nbns_getaddrinfo(const char *name, struct nb_ctx *nbc, struct addrinfo **res)
{
	struct addrinfo *nai = NULL;
	struct sockaddr *sap = NULL;
	char *ucname = NULL;
	int err;

	/*
	 * Try NetBIOS name lookup.
	 */
	if (strlen(name) >= NB_NAMELEN) {
		err = EAI_OVERFLOW;
		goto out;
	}
	ucname = utf8_str_toupper(name);
	if (ucname == NULL)
		goto nomem;

	/* Note: this returns an NBERROR value. */
	err = nbns_resolvename(ucname, nbc, &sap);
	if (err) {
		if (smb_verbose)
			smb_error(dgettext(TEXT_DOMAIN,
			    "nbns_resolvename: %s"),
			    err, name);
		err = EAI_NODATA;
		goto out;
	}
	/* Note: sap allocated */

	/*
	 * Build the addrinfo struct to return.
	 */
	nai = malloc(sizeof (*nai));
	if (nai == NULL)
		goto nomem;
	bzero(nai, sizeof (*nai));

	nai->ai_flags = AI_CANONNAME;
	nai->ai_family = sap->sa_family;
	nai->ai_socktype = SOCK_STREAM;
	nai->ai_canonname = ucname;
	ucname = NULL;

	/*
	 * The type of this is really sockaddr_in,
	 * but is returned in the generic form.
	 * See nbns_resolvename.
	 */
	nai->ai_addrlen = sizeof (struct sockaddr_in);
	nai->ai_addr = sap;

	*res = nai;
	return (0);

nomem:
	err = EAI_MEMORY;
out:
	if (nai != NULL)
		free(nai);
	if (sap)
		free(sap);
	if (ucname)
		free(ucname);
	*res = NULL;

	return (err);
}