/* * smb_tonetbiosname * * Creates a NetBIOS name based on the given name and suffix. * NetBIOS name is 15 capital characters, padded with space if needed * and the 16th byte is the suffix. */ void smb_tonetbiosname(char *name, char *nb_name, char suffix) { char tmp_name[NETBIOS_NAME_SZ]; smb_wchar_t wtmp_name[NETBIOS_NAME_SZ]; int len; size_t rc; len = 0; rc = smb_mbstowcs(wtmp_name, (const char *)name, NETBIOS_NAME_SZ); if (rc != (size_t)-1) { wtmp_name[NETBIOS_NAME_SZ - 1] = 0; rc = ucstooem(tmp_name, wtmp_name, NETBIOS_NAME_SZ, OEM_CPG_850); if (rc > 0) len = strlen(tmp_name); } (void) memset(nb_name, ' ', NETBIOS_NAME_SZ - 1); if (len) { (void) smb_strupr(tmp_name); (void) memcpy(nb_name, tmp_name, len); } nb_name[NETBIOS_NAME_SZ - 1] = suffix; }
/* * Generate an OEM name for the given share name. If the name is * shorter than 13 bytes the oemname will be returned; otherwise NULL * is returned. */ static char * smb_kshare_oemname(const char *shrname) { smb_wchar_t *unibuf; char *oem_name; int length; length = strlen(shrname) + 1; oem_name = smb_mem_alloc(length); unibuf = smb_mem_alloc(length * sizeof (smb_wchar_t)); (void) smb_mbstowcs(unibuf, shrname, length); if (ucstooem(oem_name, unibuf, length, OEM_CPG_850) == 0) (void) strcpy(oem_name, shrname); smb_mem_free(unibuf); if (strlen(oem_name) + 1 > SMB_SHARE_OEMNAME_MAX) { smb_mem_free(oem_name); return (NULL); } return (oem_name); }
/* * This fills in a samr_user_password (a.k.a. SAMPR_USER_PASSWORD * in the MS Net API) which has the new password "right justified" * in the buffer, and any space on the left filled with random junk * to improve the quality of the encryption that is subsequently * applied to this buffer before it goes over the wire. */ static void samr_fill_userpw(struct samr_user_password *upw, const char *new_pw) { smb_wchar_t *pbuf; uint32_t pwlen_bytes; size_t pwlen_wchars; /* * First fill the whole buffer with the random junk. * (Slightly less random when debugging:) */ #ifdef DEBUG (void) memset(upw->Buffer, '*', sizeof (upw->Buffer)); #else randomize((char *)upw->Buffer, sizeof (upw->Buffer)); #endif /* * Now overwrite the last pwlen characters of * that buffer with the password, and set the * length field so the receiving end knows where * the junk ends and the real password starts. */ pwlen_wchars = smb_wcequiv_strlen(new_pw) / 2; if (pwlen_wchars > SAMR_USER_PWLEN) pwlen_wchars = SAMR_USER_PWLEN; pwlen_bytes = pwlen_wchars * 2; pbuf = &upw->Buffer[SAMR_USER_PWLEN - pwlen_wchars]; (void) smb_mbstowcs(pbuf, new_pw, pwlen_wchars); /* Yes, this is in Bytes, not wchars. */ upw->Length = htolel(pwlen_bytes); }
void smb_rpc_off(char *dst, char *src, uint32_t *offset, uint32_t *outoffset) { int nwchars; int bytes; bytes = smb_wcequiv_strlen(src) + 2; nwchars = strlen(src) + 1; *offset -= bytes; *outoffset = *offset; /*LINTED E_BAD_PTR_CAST_ALIGN*/ (void) smb_mbstowcs(((smb_wchar_t *)(dst + *offset)), src, nwchars); }
/* * Our regular string marshalling always creates null terminated strings * but some Windows clients and servers are pedantic about the string * formats they will accept and require non-null terminated strings. * This function can be used to build a wide-char, non-null terminated * string in the heap as a varying/conformant array. We need to do the * wide-char conversion here because the marshalling code won't be * aware that this is really a string. */ void ndr_heap_mkvcs(ndr_heap_t *heap, char *s, ndr_vcstr_t *vc) { int mlen; vc->wclen = smb_wcequiv_strlen(s); vc->wcsize = vc->wclen; mlen = sizeof (ndr_vcs_t) + vc->wcsize + sizeof (smb_wchar_t); vc->vcs = ndr_heap_malloc(heap, mlen); if (vc->vcs) { vc->vcs->vc_first_is = 0; vc->vcs->vc_length_is = vc->wclen / sizeof (smb_wchar_t); (void) smb_mbstowcs((smb_wchar_t *)vc->vcs->buffer, s, vc->vcs->vc_length_is); } }
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 *)¶m->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); }