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); }
/*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); }
/* * 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); }