Ejemplo n.º 1
0
/*
 * GetPrinterData is used t obtain values from the registry for a
 * printer or a print server.  See [MS-RPRN] for value descriptions.
 * The registry returns ERROR_FILE_NOT_FOUND for unknown keys.
 */
static int
spoolss_s_GetPrinterData(void *arg, ndr_xa_t *mxa)
{
	static spoolss_winreg_t	reg[] = {
		{ "ChangeId",			0x0050acf2 },
		{ "W3SvcInstalled",		0x00000000 },
		{ "BeepEnabled",		0x00000000 },
		{ "EventLog",			0x0000001f },
		{ "NetPopup",			0x00000000 },
		{ "NetPopupToComputer",		0x00000000 },
		{ "MajorVersion",		0x00000003 },
		{ "MinorVersion",		0x00000000 },
		{ "DsPresent",			0x00000000 }
	};

	struct spoolss_GetPrinterData *param = arg;
	char			*name = (char *)param->pValueName;
	char			buf[MAXPATHLEN];
	static uint8_t		reserved_buf[4];
	spoolss_winreg_t	*rp;
	smb_share_t		si;
	smb_version_t		*osversion;
	struct utsname		sysname;
	smb_wchar_t		*wcs;
	uint32_t		value;
	uint32_t		status;
	int			wcslen;
	int			i;

	if (name == NULL || *name == '\0') {
		status = ERROR_FILE_NOT_FOUND;
		goto report_error;
	}

	for (i = 0; i < sizeof (reg) / sizeof (reg[0]); ++i) {
		param->pType = WINREG_DWORD;
		param->Needed = sizeof (uint32_t);
		rp = &reg[i];

		if (strcasecmp(name, rp->name) != 0)
			continue;

		if (param->Size < sizeof (uint32_t)) {
			param->Size = 0;
			goto need_more_data;
		}

		if ((param->Buf = NDR_NEW(mxa, uint32_t)) == NULL) {
			status = ERROR_NOT_ENOUGH_MEMORY;
			goto report_error;
		}

		value = rp->value;

		if ((strcasecmp(name, "DsPresent") == 0) &&
		    (smb_config_get_secmode() == SMB_SECMODE_DOMAIN))
			value = 0x00000001;

		bcopy(&value, param->Buf, sizeof (uint32_t));
		param->Size = sizeof (uint32_t);
		param->status = ERROR_SUCCESS;
		return (NDR_DRC_OK);
	}

	if (strcasecmp(name, "OSVersion") == 0) {
		param->pType = WINREG_BINARY;
		param->Needed = sizeof (smb_version_t);

		if (param->Size < sizeof (smb_version_t)) {
			param->Size = sizeof (smb_version_t);
			goto need_more_data;
		}

		if ((osversion = NDR_NEW(mxa, smb_version_t)) == NULL) {
			status = ERROR_NOT_ENOUGH_MEMORY;
			goto report_error;
		}

		smb_config_get_version(osversion);
		param->Buf = (uint8_t *)osversion;
		param->status = ERROR_SUCCESS;
		return (NDR_DRC_OK);
	}

	if (strcasecmp(name, "DNSMachineName") == 0) {
		param->pType = WINREG_SZ;
		buf[0] = '\0';
		(void) smb_getfqhostname(buf, MAXHOSTNAMELEN);
		goto encode_string;
	}

	if (strcasecmp(name, "DefaultSpoolDirectory") == 0) {
		param->pType = WINREG_SZ;
		buf[0] = '\0';

		if (smb_shr_get(SMB_SHARE_PRINT, &si) != NERR_Success) {
			status = ERROR_FILE_NOT_FOUND;
			goto report_error;
		}

		(void) snprintf(buf, MAXPATHLEN, "C:/%s", si.shr_path);
		(void) strcanon(buf, "/\\");
		(void) strsubst(buf, '/', '\\');
		goto encode_string;
	}

	if (strcasecmp(name, "Architecture") == 0) {
		param->pType = WINREG_SZ;

		if (uname(&sysname) < 0)
			(void) strlcpy(buf, "Solaris", MAXPATHLEN);
		else
			(void) snprintf(buf, MAXPATHLEN, "%s %s",
			    sysname.sysname, sysname.machine);

		goto encode_string;
	}

	status = ERROR_FILE_NOT_FOUND;

report_error:
	bzero(param, sizeof (struct spoolss_GetPrinterData));
	param->Buf = reserved_buf;
	param->status = status;
	return (NDR_DRC_OK);

encode_string:
	wcslen = smb_wcequiv_strlen(buf) + sizeof (smb_wchar_t);
	if (param->Size < wcslen) {
		param->Needed = wcslen;
		goto need_more_data;
	}

	if ((wcs = NDR_MALLOC(mxa, wcslen)) == NULL) {
		status = ERROR_NOT_ENOUGH_MEMORY;
		goto report_error;
	}

	(void) ndr_mbstowcs(NULL, wcs, buf, wcslen);
	param->Buf = (uint8_t *)wcs;
	param->Needed = wcslen;
	param->status = ERROR_SUCCESS;
	return (NDR_DRC_OK);

need_more_data:
	param->Size = 0;
	param->Buf = reserved_buf;
	param->status = ERROR_MORE_DATA;
	return (NDR_DRC_OK);
}
Ejemplo n.º 2
0
/*
 * 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));
}