Example #1
0
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);
}
Example #2
0
/*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);
}
Example #3
0
/*
 * All versions of windows use this function to spool files to a printer
 * via the cups interface
 */
static void
smbd_spool_copyfile(smb_inaddr_t *ipaddr, char *username, char *path,
                    char *doc_name)
{
    smb_cups_ops_t	*cups;
    http_t		*http = NULL;		/* HTTP connection to server */
    ipp_t		*request = NULL;	/* IPP Request */
    ipp_t		*response = NULL;	/* IPP Response */
    cups_lang_t	*language = NULL;	/* Default language */
    char		uri[HTTP_MAX_URI];	/* printer-uri attribute */
    char		new_jobname[SMBD_PJOBLEN];
    smbd_printjob_t	pjob;
    char		clientname[INET6_ADDRSTRLEN];
    struct stat 	sbuf;
    int		rc = 1;

    if (stat(path, &sbuf)) {
        syslog(LOG_INFO, "smbd_spool_copyfile: %s: %s",
               path, strerror(errno));
        return;
    }

    /*
     * Remove zero size files and return; these were inadvertantly
     * created by XP or 2000.
     */
    if (sbuf.st_size == 0) {
        if (remove(path) != 0)
            syslog(LOG_INFO,
                   "smbd_spool_copyfile: cannot remove %s: %s",
                   path, strerror(errno));
        return;
    }

    if ((cups = smbd_cups_ops()) == NULL)
        return;

    if ((http = cups->httpConnect("localhost", 631)) == NULL) {
        syslog(LOG_INFO,
               "smbd_spool_copyfile: cupsd not running");
        return;
    }

    if ((request = cups->ippNew()) == NULL) {
        syslog(LOG_INFO,
               "smbd_spool_copyfile: ipp not running");
        return;
    }

    request->request.op.operation_id = IPP_PRINT_JOB;
    request->request.op.request_id = 1;
    language = cups->cupsLangDefault();

    cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
                       "attributes-charset", NULL, cups->cupsLangEncoding(language));

    cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                       "attributes-natural-language", NULL, language->language);

    (void) snprintf(uri, sizeof (uri), "ipp://localhost/printers/%s",
                    SMBD_PRINTER);
    pjob.pj_pid = pthread_self();
    pjob.pj_sysjob = 10;
    (void) strlcpy(pjob.pj_filename, path, SMBD_PJOBLEN);
    pjob.pj_start_time = time(NULL);
    pjob.pj_status = 2;
    pjob.pj_size = sbuf.st_blocks * 512;
    pjob.pj_page_count = 1;
    pjob.pj_isspooled = B_TRUE;
    pjob.pj_jobnum = smbd_cups_jobnum;

    (void) strlcpy(pjob.pj_jobname, doc_name, SMBD_PJOBLEN);
    (void) strlcpy(pjob.pj_username, username, SMBD_PJOBLEN);
    (void) strlcpy(pjob.pj_queuename, SMBD_CUPS_SPOOL_DIR, SMBD_PJOBLEN);

    cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
                       "printer-uri", NULL, uri);

    cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                       "requesting-user-name", NULL, pjob.pj_username);

    if (smb_inet_ntop(ipaddr, clientname,
                      SMB_IPSTRLEN(ipaddr->a_family)) == NULL) {
        syslog(LOG_INFO,
               "smbd_spool_copyfile: %s: unknown client", clientname);
        goto out;
    }

    cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                       "job-originating-host-name", NULL, clientname);

    (void) snprintf(new_jobname, SMBD_PJOBLEN, "%s%d",
                    SMBD_FN_PREFIX, pjob.pj_jobnum);
    cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                       "job-name", NULL, new_jobname);

    (void) snprintf(uri, sizeof (uri) - 1, "/printers/%s", SMBD_PRINTER);

    response = cups->cupsDoFileRequest(http, request, uri,
                                       pjob.pj_filename);
    if (response != NULL) {
        if (response->request.status.status_code >= IPP_OK_CONFLICT) {
            syslog(LOG_ERR,
                   "smbd_spool_copyfile: printer %s: %s",
                   SMBD_PRINTER,
                   cups->ippErrorString(cups->cupsLastError()));
        } else {
            atomic_inc_32(&smbd_cups_jobnum);
            rc = 0;
        }
    } else {
        syslog(LOG_ERR,
               "smbd_spool_copyfile: unable to print to %s",
               cups->ippErrorString(cups->cupsLastError()));
    }

    if (rc == 0)
        (void) unlink(pjob.pj_filename);

out:
    if (response)
        cups->ippDelete(response);

    if (language)
        cups->cupsLangFree(language);

    if (http)
        cups->httpClose(http);
}
smb_sdrc_t
smb_com_session_setup_andx(smb_request_t *sr)
{
	smb_sessionsetup_info_t sinfo;
	smb_session_key_t *session_key = NULL;
	char ipaddr_buf[INET6_ADDRSTRLEN];
	int native_lm;
	int auth_res;
	int rc;

	bzero(&sinfo, sizeof (smb_sessionsetup_info_t));

	if (sr->session->dialect >= NT_LM_0_12) {
		rc = smbsr_decode_vwv(sr, "b.wwwwlww4.l", &sr->andx_com,
		    &sr->andx_off, &sinfo.ssi_maxbufsize,
		    &sinfo.ssi_maxmpxcount, &sinfo.ssi_vcnumber,
		    &sinfo.ssi_sesskey, &sinfo.ssi_cipwlen,
		    &sinfo.ssi_cspwlen, &sinfo.ssi_capabilities);

		if (rc != 0)
			return (SDRC_ERROR);

		sinfo.ssi_cipwd = kmem_alloc(sinfo.ssi_cipwlen + 1, KM_SLEEP);
		sinfo.ssi_cspwd = kmem_alloc(sinfo.ssi_cspwlen + 1, KM_SLEEP);

		/*
		 * The padding between the Native OS and Native LM is a
		 * bit strange. On NT4.0, there is a 2 byte pad between
		 * the OS (Windows NT 1381) and LM (Windows NT 4.0).
		 * On Windows 2000, there is no padding between the OS
		 * (Windows 2000 2195) and LM (Windows 2000 5.0).
		 *
		 * If the padding is removed from this decode string
		 * the NT4.0 LM comes out as an empty string.
		 *
		 * So if the client's native OS is Win NT we consider
		 * the padding otherwise we don't.
		 */
		rc = smbsr_decode_data(sr, "%#c#cuuu",
		    sr,
		    sinfo.ssi_cipwlen, sinfo.ssi_cipwd,
		    sinfo.ssi_cspwlen, sinfo.ssi_cspwd,
		    &sinfo.ssi_user,
		    &sinfo.ssi_domain,
		    &sinfo.ssi_native_os);

		if (rc != 0) {
			kmem_free(sinfo.ssi_cipwd, sinfo.ssi_cipwlen + 1);
			kmem_free(sinfo.ssi_cspwd, sinfo.ssi_cspwlen + 1);
			return (SDRC_ERROR);
		}

		sinfo.ssi_cipwd[sinfo.ssi_cipwlen] = 0;
		sinfo.ssi_cspwd[sinfo.ssi_cspwlen] = 0;

		sr->session->native_os =
		    smbnative_os_value(sinfo.ssi_native_os);

		if (sr->session->native_os == NATIVE_OS_WINNT)
			rc = smbsr_decode_data(sr, "%,u", sr,
			    &sinfo.ssi_native_lm);
		else
			rc = smbsr_decode_data(sr, "%u", sr,
			    &sinfo.ssi_native_lm);

		/*
		 * If the Native Lanman cannot be determined,
		 * default to Windows NT.
		 */
		if (rc != 0 || sinfo.ssi_native_lm == NULL)
			sinfo.ssi_native_lm = "NT LAN Manager 4.0";
	} else {
		rc = smbsr_decode_vwv(sr, "b.wwwwlw4.", &sr->andx_com,
		    &sr->andx_off, &sinfo.ssi_maxbufsize,
		    &sinfo.ssi_maxmpxcount,
		    &sinfo.ssi_vcnumber, &sinfo.ssi_sesskey,
		    &sinfo.ssi_cipwlen);

		if (rc != 0)
			return (SDRC_ERROR);

		sinfo.ssi_cipwd = kmem_alloc(sinfo.ssi_cipwlen + 1, KM_SLEEP);
		rc = smbsr_decode_data(sr, "%#c", sr, sinfo.ssi_cipwlen,
		    sinfo.ssi_cipwd);
		if (rc != 0) {
			kmem_free(sinfo.ssi_cipwd, sinfo.ssi_cipwlen + 1);
			return (SDRC_ERROR);
		}

		sinfo.ssi_cipwd[sinfo.ssi_cipwlen] = 0;

		/*
		 * Despite the CIFS/1.0 spec, the rest of this message is
		 * not always present. We need to try to get the account
		 * name and the primary domain but we don't care about the
		 * the native OS or native LanMan fields.
		 */
		if (smbsr_decode_data(sr, "%u", sr, &sinfo.ssi_user) != 0)
			sinfo.ssi_user = "";

		if (smbsr_decode_data(sr, "%u", sr, &sinfo.ssi_domain) != 0)
			sinfo.ssi_domain = "";

		sr->session->native_os = NATIVE_OS_WINNT;
		sinfo.ssi_native_lm = "NT LAN Manager 4.0";
	}

	/*
	 * If the sinfo.ssi_vcnumber is zero, we can discard any
	 * other connections associated with this client.
	 */
	sr->session->vcnumber = sinfo.ssi_vcnumber;
	if (sinfo.ssi_vcnumber == 0)
		smb_server_reconnection_check(sr->sr_server, sr->session);

	auth_res = smb_authenticate(sr, &sinfo, &session_key);

	if (sinfo.ssi_cipwd)
		kmem_free(sinfo.ssi_cipwd, sinfo.ssi_cipwlen + 1);

	if (auth_res == SMB_AUTH_FAILED) {
		if (sinfo.ssi_cspwd)
			kmem_free(sinfo.ssi_cspwd, sinfo.ssi_cspwlen + 1);
		return (SDRC_ERROR);
	}

	native_lm = smbnative_lm_value(sinfo.ssi_native_lm);
	if (native_lm == NATIVE_LM_WIN2000)
		sinfo.ssi_capabilities |= CAP_LARGE_FILES |
		    CAP_LARGE_READX | CAP_LARGE_WRITEX;

	sr->session->smb_msg_size = sinfo.ssi_maxbufsize;
	sr->session->capabilities = sinfo.ssi_capabilities;

	/*
	 * Check to see if SMB signing is enable, but if it is already turned
	 * on leave it.
	 * The first authenticated logon provides the MAC key and sequence
	 * numbers for signing all further session on the
	 * same network connection.
	 */
	if (!(sr->session->signing.flags & SMB_SIGNING_ENABLED) &&
	    (sr->session->secmode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) &&
	    (sr->smb_flg2 & SMB_FLAGS2_SMB_SECURITY_SIGNATURE) &&
	    session_key)
		smb_sign_init(sr, session_key, (char *)sinfo.ssi_cspwd,
		    sinfo.ssi_cspwlen);

	if (sinfo.ssi_cspwd)
		kmem_free(sinfo.ssi_cspwd, sinfo.ssi_cspwlen + 1);

	if (session_key)
		kmem_free(session_key, sizeof (smb_session_key_t));

	if (!(sr->smb_flg2 & SMB_FLAGS2_SMB_SECURITY_SIGNATURE) &&
	    (sr->sr_cfg->skc_signing_required)) {
		(void) smb_inet_ntop(&sr->session->ipaddr, ipaddr_buf,
		    SMB_IPSTRLEN(sr->session->ipaddr.a_family));
		cmn_err(CE_NOTE,
		    "SmbSessonSetupX: client %s is not capable of signing",
		    ipaddr_buf);
		smbsr_error(sr, NT_STATUS_LOGON_FAILURE,
		    ERRDOS, ERROR_LOGON_FAILURE);
		return (SDRC_ERROR);
	}

	/*
	 * NT systems use different native OS and native LanMan values
	 * dependent on whether they are acting as a client or a server.
	 * As a server, NT 4.0 responds with the following values:
	 *
	 *	NativeOS:	Windows NT 4.0
	 *	NativeLM:	NT LAN Manager 4.0
	 *
	 * We should probably use the same values as NT but this code has
	 * been using the product name and "Windows NT 4.0" for a long time
	 * and I don't know if a change would cause any problems (see the
	 * conditional test below).
	 */
	rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%uuu",
	    3,
	    sr->andx_com,
	    -1,			/* andx_off */
	    (auth_res == SMB_AUTH_GUEST) ? 1 : 0,
	    VAR_BCC,
	    sr,
	    "Windows NT 4.0",
	    "NT LAN Manager 4.0",
	    sr->sr_cfg->skc_nbdomain);

	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
}