Example #1
0
static uint32_t
spoolss_format_sd(smb_sd_t *sd)
{
	smb_fssd_t	fs_sd;
	acl_t		*acl;
	uint32_t	status = ERROR_SUCCESS;

	if (acl_fromtext("everyone@:full_set::allow", &acl) != 0) {
		smb_tracef("spoolss_format_sd: NOT_ENOUGH_MEMORY");
		return (ERROR_NOT_ENOUGH_MEMORY);
	}
	smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR);
	fs_sd.sd_uid = 0;
	fs_sd.sd_gid = 0;
	fs_sd.sd_zdacl = acl;
	fs_sd.sd_zsacl = NULL;

	status = smb_sd_fromfs(&fs_sd, sd);
	if (status != NT_STATUS_SUCCESS) {
		smb_tracef("spoolss_format_sd: %u", status);
		status = ERROR_ACCESS_DENIED;
	}
	smb_fssd_term(&fs_sd);
	return (status);
}
Example #2
0
void
srvsvc_net_test(char *server, char *domain, char *netname)
{
	smb_domainex_t di;
	srvsvc_server_info_t svinfo;

	(void) smb_tracef("%s %s %s", server, domain, netname);

	if (smb_domain_getinfo(&di)) {
		server = di.d_dc;
		domain = di.d_primary.di_nbname;
	}

	if (srvsvc_net_server_getinfo(server, domain, &svinfo) == 0) {
		smb_tracef("NetServerGetInfo: %s %s (%d.%d) id=%d type=0x%08x",
		    svinfo.sv_name ? svinfo.sv_name : "NULL",
		    svinfo.sv_comment ? svinfo.sv_comment : "NULL",
		    svinfo.sv_version_major, svinfo.sv_version_minor,
		    svinfo.sv_platform_id, svinfo.sv_type);

		free(svinfo.sv_name);
		free(svinfo.sv_comment);
	}

	(void) srvsvc_net_share_get_info(server, domain, netname);
#if 0
	/*
	 * The NetSessionEnum server-side definition was updated.
	 * Disabled until the client-side has been updated.
	 */
	(void) srvsvc_net_session_enum(server, domain, netname);
#endif
	(void) srvsvc_net_connect_enum(server, domain, netname, 0);
	(void) srvsvc_net_connect_enum(server, domain, netname, 1);
}
Example #3
0
/*
 * Use the RPC context handle to find the fd and write the document content.
 */
static int
spoolss_s_WritePrinter(void *arg, ndr_xa_t *mxa)
{
	struct spoolss_WritePrinter *param = arg;
	int written = 0;
	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
	int spfd;

	if (ndr_hdlookup(mxa, id) == NULL) {
		param->written = 0;
		param->status = ERROR_INVALID_HANDLE;
		smb_tracef("spoolss_s_WritePrinter: invalid handle");
		return (NDR_DRC_OK);
	}

	if ((spfd = spoolss_find_document(id)) < 0) {
		param->written = 0;
		param->status = ERROR_INVALID_HANDLE;
		smb_tracef("spoolss_s_WritePrinter: document not found");
		return (NDR_DRC_OK);
	}

	written = write(spfd, param->pBuf, param->BufCount);
	if (written < param->BufCount) {
		smb_tracef("spoolss_s_WritePrinter: write failed");
		param->written = 0;
		param->status = ERROR_CANTWRITE;
		return (NDR_DRC_OK);
	}

	param->written = written;
	param->status = ERROR_SUCCESS;
	return (NDR_DRC_OK);
}
Example #4
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 #5
0
/*
 * sam_create_account
 *
 * Create the specified domain account in the SAM database on the
 * domain controller.
 *
 * Account flags:
 *		SAMR_AF_NORMAL_ACCOUNT
 *		SAMR_AF_WORKSTATION_TRUST_ACCOUNT
 *		SAMR_AF_SERVER_TRUST_ACCOUNT
 *
 * Returns NT status codes.
 */
DWORD
sam_create_account(char *server, char *domain_name, char *account_name,
    DWORD account_flags)
{
	mlsvc_handle_t samr_handle;
	mlsvc_handle_t domain_handle;
	mlsvc_handle_t user_handle;
	union samr_user_info sui;
	struct samr_sid *sid;
	DWORD rid;
	DWORD status;
	int rc;
	char user[SMB_USERNAME_MAXLEN];

	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);

	rc = samr_open(server, domain_name, user, SAM_CONNECT_CREATE_ACCOUNT,
	    &samr_handle);

	if (rc != 0) {
		status = NT_STATUS_OPEN_FAILED;
		smb_tracef("SamCreateAccount[%s\\%s]: %s",
		    domain_name, account_name, xlate_nt_status(status));
		return (status);
	}

	sid = sam_get_domain_sid(&samr_handle, server, domain_name);

	status = samr_open_domain(&samr_handle,
	    SAM_DOMAIN_CREATE_ACCOUNT, sid, &domain_handle);

	if (status == NT_STATUS_SUCCESS) {
		status = samr_create_user(&domain_handle, account_name,
		    account_flags, &rid, &user_handle);

		if (status == NT_STATUS_SUCCESS) {
			(void) samr_query_user_info(&user_handle,
			    SAMR_QUERY_USER_CONTROL_INFO, &sui);

			(void) samr_get_user_pwinfo(&user_handle);
			(void) samr_set_user_info(&user_handle);
			(void) samr_close_handle(&user_handle);
		} else if (status != NT_STATUS_USER_EXISTS) {
			smb_tracef("SamCreateAccount[%s]: %s",
			    account_name, xlate_nt_status(status));
		}

		(void) samr_close_handle(&domain_handle);
	} else {
		smb_tracef("SamCreateAccount[%s]: open domain failed",
		    account_name);
		status = (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
	}

	(void) samr_close_handle(&samr_handle);
	free(sid);
	return (status);
}
Example #6
0
void
ndr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status)
{
	ndr_service_t *svc;
	char *name = "NDR RPC";
	char *s = "unknown";

	switch (NT_SC_SEVERITY(status)) {
	case NT_STATUS_SEVERITY_SUCCESS:
		s = "success";
		break;
	case NT_STATUS_SEVERITY_INFORMATIONAL:
		s = "info";
		break;
	case NT_STATUS_SEVERITY_WARNING:
		s = "warning";
		break;
	case NT_STATUS_SEVERITY_ERROR:
		s = "error";
		break;
	}

	if (handle) {
		svc = handle->clnt->binding->service;
		name = svc->name;
	}

	smb_tracef("%s[0x%02x]: %s: %s (0x%08x)",
	    name, opnum, s, xlate_nt_status(status), status);
}
Example #7
0
/*
 * Lookup a sid and obtain the domain sid and account name.
 * This is a wrapper for the various lookup sid RPCs.
 */
uint32_t
lsar_lookup_sids(mlsvc_handle_t *lsa_handle, smb_sid_t *sid,
    smb_account_t *account)
{
	char		sidbuf[SMB_SID_STRSZ];
	uint32_t	status;

	if (lsa_handle == NULL || sid == NULL || account == NULL)
		return (NT_STATUS_INVALID_PARAMETER);

	bzero(account, sizeof (smb_account_t));
	bzero(sidbuf, SMB_SID_STRSZ);
	smb_sid_tostr(sid, sidbuf);
	smb_tracef("%s", sidbuf);

	if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000)
		status = lsar_lookup_sids2(lsa_handle, (lsa_sid_t *)sid,
		    account);
	else
		status = lsar_lookup_sids1(lsa_handle, (lsa_sid_t *)sid,
		    account);

	if (status == NT_STATUS_SUCCESS) {
		if (!smb_account_validate(account)) {
			smb_account_free(account);
			status = NT_STATUS_NO_MEMORY;
		} else {
			smb_account_trace(account);
		}
	}

	return (status);
}
Example #8
0
static int
spoolss_s_OpenPrinter(void *arg, ndr_xa_t *mxa)
{
	struct spoolss_OpenPrinter *param = arg;
	char		*name = (char *)param->printer_name;
	ndr_hdid_t	*id;

	if (name != NULL && *name != '\0') {
		if (strspn(name, "\\") > 2) {
			bzero(&param->handle, sizeof (spoolss_handle_t));
			param->status = ERROR_INVALID_PRINTER_NAME;
			return (NDR_DRC_OK);
		}

		smb_tracef("spoolss_s_OpenPrinter: %s", name);
	}

	if ((id = ndr_hdalloc(mxa, NULL)) == NULL) {
		bzero(&param->handle, sizeof (spoolss_handle_t));
		param->status = ERROR_NOT_ENOUGH_MEMORY;
		return (NDR_DRC_OK);
	}

	bcopy(id, &param->handle, sizeof (spoolss_handle_t));
	param->status = 0;
	return (NDR_DRC_OK);
}
Example #9
0
/*
 * This is a client side routine for NetSessionEnum.
 * NetSessionEnum requires administrator rights.
 */
int
srvsvc_net_session_enum(char *server, char *domain, char *netname)
{
	struct mslm_NetSessionEnum arg;
	mlsvc_handle_t handle;
	int rc;
	int opnum;
	struct mslm_infonres infonres;
	struct mslm_SESSION_INFO_1 *nsi1;
	int len;
	char user[SMB_USERNAME_MAXLEN];

	if (netname == NULL)
		return (-1);

	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);

	rc = srvsvc_open(server, domain, user, &handle);
	if (rc != 0)
		return (-1);

	opnum = SRVSVC_OPNUM_NetSessionEnum;
	bzero(&arg, sizeof (struct mslm_NetSessionEnum));

	len = strlen(server) + 4;
	arg.servername = ndr_rpc_malloc(&handle, len);
	if (arg.servername == NULL) {
		srvsvc_close(&handle);
		return (-1);
	}

	(void) snprintf((char *)arg.servername, len, "\\\\%s", server);
	infonres.entriesread = 0;
	infonres.entries = 0;
	arg.level = 1;
	arg.result.level = 1;
	arg.result.bufptr.p = &infonres;
	arg.resume_handle = 0;
	arg.pref_max_len = 0xFFFFFFFF;

	rc = ndr_rpc_call(&handle, opnum, &arg);
	if ((rc != 0) || (arg.status != 0)) {
		srvsvc_close(&handle);
		return (-1);
	}

	/* Only the first session info is dereferenced. */
	nsi1 = ((struct mslm_infonres *)arg.result.bufptr.p)->entries;

	smb_tracef("srvsvc switch_value=%d", arg.level);
	smb_tracef("srvsvc sesi1_cname=%s", nsi1->sesi1_cname);
	smb_tracef("srvsvc sesi1_uname=%s", nsi1->sesi1_uname);
	smb_tracef("srvsvc sesi1_nopens=%u", nsi1->sesi1_nopens);
	smb_tracef("srvsvc sesi1_time=%u", nsi1->sesi1_time);
	smb_tracef("srvsvc sesi1_itime=%u", nsi1->sesi1_itime);
	smb_tracef("srvsvc sesi1_uflags=%u", nsi1->sesi1_uflags);

	srvsvc_close(&handle);
	return (0);
}
Example #10
0
/*
 *
 * hexdump
 *
 * Simple hex dump display function. Displays nbytes of buffer in hex and
 * printable format. Non-printing characters are shown as '.'. It is safe
 * to pass a null pointer. Each line begins with the offset. If nbytes is
 * 0, the line will be blank except for the offset. Example output:
 *
 * 00000000  54 68 69 73 20 69 73 20 61 20 70 72 6F 67 72 61  This is a progra
 * 00000010  6D 20 74 65 73 74 2E 00                          m test..
 *
 */
void
hexdump_offset(unsigned char *buffer, int nbytes, unsigned long *start)
{
	static char *hex = "0123456789ABCDEF";
	int i, count;
	int offset;
	unsigned char *p;
	char ascbuf[64];
	char hexbuf[64];
	char *ap = ascbuf;
	char *hp = hexbuf;

	if ((p = buffer) == NULL)
		return;

	offset = *start;

	*ap = '\0';
	*hp = '\0';
	count = 0;

	for (i = 0; i < nbytes; ++i) {
		if (i && (i % 16) == 0) {
			smb_tracef("%06X %s  %s", offset, hexbuf, ascbuf);
			ap = ascbuf;
			hp = hexbuf;
			count = 0;
			offset += 16;
		}

		ap += sprintf(ap, "%c",
		    (*p >= 0x20 && *p < 0x7F) ? *p : '.');
		hp += sprintf(hp, " %c%c",
		    hex[(*p >> 4) & 0x0F], hex[(*p & 0x0F)]);
		++p;
		++count;
	}

	if (count) {
		smb_tracef("%06X %-48s  %s", offset, hexbuf, ascbuf);
		offset += count;
	}

	*start = offset;
}
Example #11
0
static void
smb_account_trace(const smb_account_t *info)
{
	char	sidbuf[SMB_SID_STRSZ];

	bzero(sidbuf, SMB_SID_STRSZ);
	smb_sid_tostr(info->a_sid, sidbuf);

	smb_tracef("%s %s %s %lu %s", info->a_domain, info->a_name,
	    sidbuf, info->a_rid, smb_sid_type2str(info->a_type));
}
Example #12
0
/*
 * samr_create_user
 *
 * Create a user in the domain specified by the domain handle. If this
 * call is successful, the server will return the RID for the user and
 * a user handle, which may be used to set or query the SAM.
 *
 * Observed status codes:
 *	NT_STATUS_INVALID_PARAMETER
 *	NT_STATUS_INVALID_ACCOUNT_NAME
 *	NT_STATUS_ACCESS_DENIED
 *	NT_STATUS_USER_EXISTS
 *
 * Returns 0 on success. Otherwise returns an NT status code.
 */
DWORD
samr_create_user(mlsvc_handle_t *domain_handle, char *username,
    DWORD account_flags, DWORD *rid, mlsvc_handle_t *user_handle)
{
	struct samr_CreateUser arg;
	ndr_heap_t *heap;
	int opnum;
	int rc;
	DWORD status = 0;

	if (ndr_is_null_handle(domain_handle) ||
	    username == NULL || rid == NULL) {
		return (NT_STATUS_INVALID_PARAMETER);
	}

	opnum = SAMR_OPNUM_CreateUser;

	bzero(&arg, sizeof (struct samr_CreateUser));
	(void) memcpy(&arg.handle, &domain_handle->handle,
	    sizeof (ndr_hdid_t));

	heap = ndr_rpc_get_heap(domain_handle);
	ndr_heap_mkvcs(heap, username, (ndr_vcstr_t *)&arg.username);

	arg.account_flags = account_flags;
	arg.desired_access = 0xE00500B0;

	rc = ndr_rpc_call(domain_handle, opnum, &arg);
	if (rc != 0) {
		status = NT_STATUS_INVALID_PARAMETER;
	} else if (arg.status != 0) {
		status = NT_SC_VALUE(arg.status);

		if (status != NT_STATUS_USER_EXISTS) {
			smb_tracef("SamrCreateUser[%s]: %s", username,
			    xlate_nt_status(status));
		}
	} else {
		ndr_inherit_handle(user_handle, domain_handle);

		(void) memcpy(&user_handle->handle, &arg.user_handle,
		    sizeof (ndr_hdid_t));

		*rid = arg.rid;

		if (ndr_is_null_handle(user_handle))
			status = NT_STATUS_INVALID_HANDLE;
		else
			status = 0;
	}

	ndr_rpc_release(domain_handle);
	return (status);
}
Example #13
0
/*
 * Synchronize the local system clock with the domain controller.
 */
void
srvsvc_timesync(void)
{
	smb_domainex_t di;
	struct timeval tv;
	struct tm tm;
	time_t tsecs;

	if (!smb_domain_getinfo(&di))
		return;

	if (srvsvc_net_remote_tod(di.d_dc, di.d_primary.di_nbname, &tv, &tm)
	    != 0)
		return;

	if (settimeofday(&tv, 0))
		smb_tracef("unable to set system time");

	tsecs = time(0);
	(void) localtime_r(&tsecs, &tm);
	smb_tracef("SrvsvcTimeSync %s", ctime((time_t *)&tv.tv_sec));
}
Example #14
0
/*
 * Windows XP and 2000 use this mechanism to write spool files
 * Search the spooldoc list for a matching RPC handle and pass
 * the spool the file for printing.
 */
static int
spoolss_s_EndDocPrinter(void *arg, ndr_xa_t *mxa)
{
	struct spoolss_EndDocPrinter *param = arg;
	ndr_hdid_t	*id = (ndr_hdid_t *)&param->handle;
	smb_spooldoc_t	*sp;

	if (ndr_hdlookup(mxa, id) == NULL) {
		smb_tracef("spoolss_s_EndDocPrinter: invalid handle");
		param->status = ERROR_INVALID_HANDLE;
		return (NDR_DRC_OK);
	}

	param->status = ERROR_INVALID_HANDLE;
	(void) rw_wrlock(&spoolss_splist.sp_rwl);

	sp = list_head(&spoolss_splist.sp_list);
	while (sp != NULL) {
		if (!memcmp(id, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
			spoolss_copyfile(&sp->sd_ipaddr,
			    sp->sd_username, sp->sd_path, sp->sd_doc_name);
			(void) close(sp->sd_fd);
			list_remove(&spoolss_splist.sp_list, sp);
			free(sp);
			param->status = ERROR_SUCCESS;
			break;
		}

		sp = list_next(&spoolss_splist.sp_list, sp);
	}

	(void) rw_unlock(&spoolss_splist.sp_rwl);

	if (param->status != ERROR_SUCCESS)
		smb_tracef("spoolss_s_EndDocPrinter: document not found");
	return (NDR_DRC_OK);
}
Example #15
0
int
spoolss_s_GetPrinter(void *arg, ndr_xa_t *mxa)
{
	struct spoolss_GetPrinter	*param = arg;
	struct spoolss_GetPrinter0	*pinfo0;
	struct spoolss_GetPrinter1	*pinfo1;
	struct spoolss_GetPrinter2	*pinfo2;
	struct spoolss_DeviceMode	*devmode2;
	ndr_hdid_t	*id = (ndr_hdid_t *)&param->handle;
	spoolss_sd_t	secdesc;
	char		server[MAXNAMELEN];
	char		printer[MAXNAMELEN];
	DWORD		status = ERROR_SUCCESS;
	char		*wname;
	uint32_t	offset;
	uint8_t		*tmpbuf;

	if (ndr_hdlookup(mxa, id) == NULL) {
		status = ERROR_INVALID_HANDLE;
		goto error_out;
	}

	if (spoolss_getservername(server, MAXNAMELEN) != 0) {
		status = ERROR_INTERNAL_ERROR;
		goto error_out;
	}

	(void) snprintf(printer, MAXNAMELEN, "%s\\%s", server, SPOOLSS_PRINTER);

	switch (param->switch_value) {
	case 0:
	case 1:
		param->needed = 460;
		break;
	case 2:
		param->needed = 712;
		break;
	default:
		status = ERROR_INVALID_LEVEL;
		goto error_out;
	}

	if (param->BufCount < param->needed) {
		param->BufCount = 0;
		param->Buf = NULL;
		param->status = ERROR_INSUFFICIENT_BUFFER;
		return (NDR_DRC_OK);
	}

	if ((param->Buf = NDR_MALLOC(mxa, param->BufCount)) == NULL) {
		status = ERROR_NOT_ENOUGH_MEMORY;
		goto error_out;
	}

	bzero(param->Buf, param->BufCount);
	wname = (char *)param->Buf;
	offset = param->needed;

	switch (param->switch_value) {
	case 0:
		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		pinfo0 = (struct spoolss_GetPrinter0 *)param->Buf;

		smb_rpc_off(wname, server, &offset, &pinfo0->servername);
		smb_rpc_off(wname, printer, &offset, &pinfo0->printername);
		pinfo0->cjobs = 0;
		pinfo0->total_jobs = 6;
		pinfo0->total_bytes = 1040771;
		pinfo0->time0 = 0;
		pinfo0->time1 = 0;
		pinfo0->time2 = 3;
		pinfo0->time3 = 0;
		pinfo0->global_counter = 2162710;
		pinfo0->total_pages = 21495865;
		pinfo0->version = 10;
		pinfo0->session_counter = 1;
		pinfo0->job_error = 0x6;
		pinfo0->change_id  = 0x1;
		pinfo0->status = 0;
		pinfo0->c_setprinter = 0;
		break;
	case 1:
		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		pinfo1 = (struct spoolss_GetPrinter1 *)param->Buf;

		pinfo1->flags = PRINTER_ENUM_ICON8;
		smb_rpc_off(wname, printer, &offset, &pinfo1->flags);
		smb_rpc_off(wname, printer, &offset, &pinfo1->description);
		smb_rpc_off(wname, printer, &offset, &pinfo1->comment);
		break;
	case 2:
		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		pinfo2 = (struct spoolss_GetPrinter2 *)param->Buf;

		smb_rpc_off(wname, server, &offset, &pinfo2->servername);
		smb_rpc_off(wname, printer, &offset, &pinfo2->printername);
		smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
		    &pinfo2->sharename);
		smb_rpc_off(wname, "CIFS Printer Port", &offset,
		    &pinfo2->portname);
		smb_rpc_off(wname, "", &offset, &pinfo2->drivername);
		smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
		    &pinfo2->comment);
		smb_rpc_off(wname, "farside", &offset, &pinfo2->location);

		offset -= sizeof (struct spoolss_DeviceMode);
		pinfo2->devmode = offset;
		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		devmode2 = (struct spoolss_DeviceMode *)(param->Buf + offset);

		smb_rpc_off(wname, "farside", &offset, &pinfo2->sepfile);
		smb_rpc_off(wname, "winprint", &offset,
		    &pinfo2->printprocessor);
		smb_rpc_off(wname, "RAW", &offset, &pinfo2->datatype);
		smb_rpc_off(wname, "", &offset, &pinfo2->parameters);

		status = spoolss_make_sd(mxa, &secdesc);
		if (status == ERROR_SUCCESS) {
			offset -= secdesc.sd_size;
			pinfo2->secdesc = offset;
			tmpbuf = (uint8_t *)(param->Buf + offset);
			bcopy(secdesc.sd_buf, tmpbuf, secdesc.sd_size);
		}

		pinfo2->attributes = 0x00001048;
		pinfo2->status = 0x00000000;
		pinfo2->starttime = 0;
		pinfo2->untiltime = 0;
		pinfo2->cjobs = 0;
		pinfo2->averageppm = 0;
		pinfo2->defaultpriority = 0;

		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		(void) smb_mbstowcs((smb_wchar_t *)devmode2->devicename,
		    printer, 32);
		devmode2->specversion = 0x0401;
		devmode2->driverversion = 1024;
		devmode2->size = 220;
		devmode2->driverextra_length = 0;
		devmode2->fields = 0x00014713;
		devmode2->orientation = 1;
		devmode2->papersize = 1;
		devmode2->paperlength = 0;
		devmode2->paperwidth = 0;
		devmode2->scale = 100;
		devmode2->copies = 1;
		devmode2->defaultsource = 15;
		devmode2->printquality = 65532;
		devmode2->color = 1;
		devmode2->duplex = 1;
		devmode2->yresolution = 1;
		devmode2->ttoption = 1;
		devmode2->collate = 0;
		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		(void) smb_mbstowcs((smb_wchar_t *)devmode2->formname,
		    "Letter", 32);
		devmode2->logpixels = 0;
		devmode2->bitsperpel = 0;
		devmode2->pelswidth = 0;
		devmode2->pelsheight = 0;
		devmode2->displayflags = 0;
		devmode2->displayfrequency = 0;
		devmode2->icmmethod = 0;
		devmode2->icmintent = 0;
		devmode2->mediatype = 0;
		devmode2->dithertype = 0;
		devmode2->reserved1 = 0;
		devmode2->reserved2 = 0;
		devmode2->panningwidth = 0;
		devmode2->panningheight = 0;
		break;

	default:
		break;
	}

	param->status = status;
	return (NDR_DRC_OK);

error_out:
	smb_tracef("spoolss_s_GetPrinter: error %u", status);
	bzero(param, sizeof (struct spoolss_GetPrinter));
	param->status = status;
	return (NDR_DRC_OK);
}
Example #16
0
/*
 * Windows XP and 2000 use this mechanism to write spool files.
 * Create a spool file fd to be used by spoolss_s_WritePrinter
 * and add it to the tail of the spool list.
 */
static int
spoolss_s_StartDocPrinter(void *arg, ndr_xa_t *mxa)
{
	struct spoolss_StartDocPrinter *param = arg;
	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
	smb_spooldoc_t *spfile;
	spoolss_DocInfo_t *docinfo;
	char g_path[MAXPATHLEN];
	smb_share_t si;
	int rc;
	int fd;

	if (ndr_hdlookup(mxa, id) == NULL) {
		smb_tracef("spoolss_s_StartDocPrinter: invalid handle");
		param->status = ERROR_INVALID_HANDLE;
		return (NDR_DRC_OK);
	}

	if ((docinfo = param->dinfo.DocInfoContainer) == NULL) {
		param->status = ERROR_INVALID_PARAMETER;
		return (NDR_DRC_OK);
	}

	if ((rc = smb_shr_get(SMB_SHARE_PRINT, &si)) != NERR_Success) {
		smb_tracef("spoolss_s_StartDocPrinter: %s error=%d",
		    SMB_SHARE_PRINT, rc);
		param->status = rc;
		return (NDR_DRC_OK);
	}

	if ((spfile = calloc(1, sizeof (smb_spooldoc_t))) == NULL) {
		param->status = ERROR_NOT_ENOUGH_MEMORY;
		return (NDR_DRC_OK);
	}

	if (docinfo->doc_name != NULL)
		(void) strlcpy(spfile->sd_doc_name,
		    (char *)docinfo->doc_name, MAXNAMELEN);
	else
		(void) strlcpy(spfile->sd_doc_name, "document", MAXNAMELEN);

	if (docinfo->printer_name != NULL)
		(void) strlcpy(spfile->sd_printer_name,
		    (char *)docinfo->printer_name, MAXPATHLEN);
	else
		(void) strlcpy(spfile->sd_printer_name, "printer", MAXPATHLEN);

	spfile->sd_ipaddr = mxa->pipe->np_user->ui_ipaddr;
	(void) strlcpy((char *)spfile->sd_username,
	    mxa->pipe->np_user->ui_account, MAXNAMELEN);
	(void) memcpy(&spfile->sd_handle, &param->handle, sizeof (ndr_hdid_t));

	/*
	 *	write temporary spool file to print$
	 */
	(void) snprintf(g_path, MAXPATHLEN, "%s/%s%d", si.shr_path,
	    spfile->sd_username, spoolss_cnt);
	atomic_inc_32(&spoolss_cnt);

	fd = open(g_path, O_CREAT | O_RDWR, 0600);
	if (fd == -1) {
		smb_tracef("spoolss_s_StartDocPrinter: %s: %s",
		    g_path, strerror(errno));
		param->status = ERROR_OPEN_FAILED;
		free(spfile);
	} else {
		(void) strlcpy((char *)spfile->sd_path, g_path, MAXPATHLEN);
		spfile->sd_fd = (uint16_t)fd;

		/*
		 * Add the document to the spool list.
		 */
		(void) rw_wrlock(&spoolss_splist.sp_rwl);
		list_insert_tail(&spoolss_splist.sp_list, spfile);
		spoolss_splist.sp_cnt++;
		(void) rw_unlock(&spoolss_splist.sp_rwl);

		/*
		 * JobId isn't used now, but if printQ management is added
		 * this will have to be incremented per job submitted.
		 */
		param->JobId = 46;
		param->status = ERROR_SUCCESS;
	}
	return (NDR_DRC_OK);
}
Example #17
0
/*
 * This is a client side routine for NetShareGetInfo.
 * Levels 0 and 1 work with an anonymous connection but
 * level 2 requires administrator access.
 */
int
srvsvc_net_share_get_info(char *server, char *domain, char *netname)
{
	struct mlsm_NetShareGetInfo arg;
	mlsvc_handle_t handle;
	int rc;
	int opnum;
	struct mslm_NetShareInfo_0 *info0;
	struct mslm_NetShareInfo_1 *info1;
	struct mslm_NetShareInfo_2 *info2;
	int len;
	char user[SMB_USERNAME_MAXLEN];

	if (netname == NULL)
		return (-1);

	if (srvsvc_info_level == 2)
		smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);

	if (srvsvc_open(server, domain, user, &handle) != 0)
		return (-1);

	opnum = SRVSVC_OPNUM_NetShareGetInfo;
	bzero(&arg, sizeof (struct mlsm_NetShareGetInfo));

	len = strlen(server) + 4;
	arg.servername = ndr_rpc_malloc(&handle, len);
	if (arg.servername == NULL) {
		srvsvc_close(&handle);
		return (-1);
	}

	(void) snprintf((char *)arg.servername, len, "\\\\%s", server);
	arg.netname = (LPTSTR)netname;
	arg.level = srvsvc_info_level; /* share information level */

	rc = ndr_rpc_call(&handle, opnum, &arg);
	if ((rc != 0) || (arg.status != 0)) {
		srvsvc_close(&handle);
		return (-1);
	}

	switch (arg.result.switch_value) {
	case 0:
		info0 = arg.result.ru.info0;
		smb_tracef("srvsvc shi0_netname=%s", info0->shi0_netname);
		break;

	case 1:
		info1 = arg.result.ru.info1;
		smb_tracef("srvsvc shi1_netname=%s", info1->shi1_netname);
		smb_tracef("srvsvc shi1_type=%u", info1->shi1_type);

		if (info1->shi1_comment)
			smb_tracef("srvsvc shi1_comment=%s",
			    info1->shi1_comment);
		break;

	case 2:
		info2 = arg.result.ru.info2;
		smb_tracef("srvsvc shi2_netname=%s", info2->shi2_netname);
		smb_tracef("srvsvc shi2_type=%u", info2->shi2_type);

		if (info2->shi2_comment)
			smb_tracef("srvsvc shi2_comment=%s",
			    info2->shi2_comment);

		smb_tracef("srvsvc shi2_perms=%d", info2->shi2_permissions);
		smb_tracef("srvsvc shi2_max_use=%d", info2->shi2_max_uses);
		smb_tracef("srvsvc shi2_cur_use=%d", info2->shi2_current_uses);

		if (info2->shi2_path)
			smb_tracef("srvsvc shi2_path=%s", info2->shi2_path);

		if (info2->shi2_passwd)
			smb_tracef("srvsvc shi2_passwd=%s", info2->shi2_passwd);
		break;

	default:
		smb_tracef("srvsvc: unknown level");
		break;
	}

	srvsvc_close(&handle);
	return (0);
}
Example #18
0
/*
 * This is a client side routine for NetConnectEnum.
 * NetConnectEnum requires administrator rights.
 * Level 0 and level 1 requests are supported.
 */
int
srvsvc_net_connect_enum(char *server, char *domain, char *netname, int level)
{
	struct mslm_NetConnectEnum arg;
	mlsvc_handle_t handle;
	int rc;
	int opnum;
	struct mslm_NetConnectInfo1 info1;
	struct mslm_NetConnectInfo0 info0;
	struct mslm_NetConnectInfoBuf1 *cib1;
	int len;
	char user[SMB_USERNAME_MAXLEN];

	if (netname == NULL)
		return (-1);

	smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);

	rc = srvsvc_open(server, domain, user, &handle);
	if (rc != 0)
		return (-1);

	opnum = SRVSVC_OPNUM_NetConnectEnum;
	bzero(&arg, sizeof (struct mslm_NetConnectEnum));

	len = strlen(server) + 4;
	arg.servername = ndr_rpc_malloc(&handle, len);
	if (arg.servername == NULL) {
		srvsvc_close(&handle);
		return (-1);
	}

	(void) snprintf((char *)arg.servername, len, "\\\\%s", server);
	arg.qualifier = (LPTSTR)netname;

	switch (level) {
	case 0:
		arg.info.level = 0;
		arg.info.switch_value = 0;
		arg.info.ru.info0 = &info0;
		info0.entries_read = 0;
		info0.ci0 = 0;
		break;
	case 1:
		arg.info.level = 1;
		arg.info.switch_value = 1;
		arg.info.ru.info1 = &info1;
		info1.entries_read = 0;
		info1.ci1 = 0;
		break;
	default:
		srvsvc_close(&handle);
		return (-1);
	}

	arg.resume_handle = 0;
	arg.pref_max_len = 0xFFFFFFFF;

	rc = ndr_rpc_call(&handle, opnum, &arg);
	if ((rc != 0) || (arg.status != 0)) {
		srvsvc_close(&handle);
		return (-1);
	}

	smb_tracef("srvsvc switch_value=%d", arg.info.switch_value);

	switch (level) {
	case 0:
		if (arg.info.ru.info0 && arg.info.ru.info0->ci0) {
			smb_tracef("srvsvc coni0_id=%x",
			    arg.info.ru.info0->ci0->coni0_id);
		}
		break;
	case 1:
		if (arg.info.ru.info1 && arg.info.ru.info1->ci1) {
			cib1 = arg.info.ru.info1->ci1;

			smb_tracef("srvsvc coni_uname=%s",
			    cib1->coni1_username ?
			    (char *)cib1->coni1_username : "******");
			smb_tracef("srvsvc coni1_netname=%s",
			    cib1->coni1_netname ?
			    (char *)cib1->coni1_netname : "(null)");
			smb_tracef("srvsvc coni1_nopens=%u",
			    cib1->coni1_num_opens);
			smb_tracef("srvsvc coni1_time=%u", cib1->coni1_time);
			smb_tracef("srvsvc coni1_num_users=%u",
			    cib1->coni1_num_users);
		}
		break;

	default:
		smb_tracef("srvsvc: unknown level");
		break;
	}

	srvsvc_close(&handle);
	return (0);
}
Example #19
0
/*
 * Trace the given DFS info structure
 */
void
dfs_info_trace(const char *msg, dfs_info_t *info)
{
	dfs_target_t *t;
	int i;

	smb_tracef("%s", msg);
	if (info == NULL)
		return;

	smb_tracef("UNC\t%s", info->i_uncpath);
	smb_tracef("comment\t%s", info->i_comment);
	smb_tracef("GUID\t%s", info->i_guid);
	smb_tracef("state\t%X", info->i_state);
	smb_tracef("timeout\t%d", info->i_timeout);
	smb_tracef("props\t%X", info->i_propflags);
	smb_tracef("# targets\t%X", info->i_ntargets);

	if (info->i_targets == NULL)
		return;

	for (i = 0, t = info->i_targets; i < info->i_ntargets; i++, t++) {
		smb_tracef("[%d] \\\\%s\\%s", i, t->t_server, t->t_share);
		smb_tracef("[%d] state\t%X", i, t->t_state);
		smb_tracef("[%d] priority\t%d:%d", i, t->t_priority.p_class,
		    t->t_priority.p_rank);
	}
}