⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nbtname.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   manipulate nbt name structures   Copyright (C) Andrew Tridgell 2005      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 3 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program.  If not, see <http://www.gnu.org/licenses/>.*//*  see rfc1002 for the detailed format of compressed names*/#include "includes.h"#include "librpc/gen_ndr/ndr_nbt.h"#include "librpc/gen_ndr/ndr_misc.h"#include "system/locale.h"#include "param/param.h"/* don't allow an unlimited number of name components */#define MAX_COMPONENTS 10/**  print a nbt string*/_PUBLIC_ void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s){	ndr_print_string(ndr, name, s);}/*  pull one component of a nbt_string*/static enum ndr_err_code ndr_pull_component(struct ndr_pull *ndr,					    uint8_t **component,					    uint32_t *offset,					    uint32_t *max_offset){	uint8_t len;	uint_t loops = 0;	while (loops < 5) {		if (*offset >= ndr->data_size) {			return ndr_pull_error(ndr, NDR_ERR_STRING,					      "BAD NBT NAME component");		}		len = ndr->data[*offset];		if (len == 0) {			*offset += 1;			*max_offset = MAX(*max_offset, *offset);			*component = NULL;			return NDR_ERR_SUCCESS;		}		if ((len & 0xC0) == 0xC0) {			/* its a label pointer */			if (1 + *offset >= ndr->data_size) {				return ndr_pull_error(ndr, NDR_ERR_STRING,						      "BAD NBT NAME component");			}			*max_offset = MAX(*max_offset, *offset + 2);			*offset = ((len&0x3F)<<8) | ndr->data[1 + *offset];			*max_offset = MAX(*max_offset, *offset);			loops++;			continue;		}		if ((len & 0xC0) != 0) {			/* its a reserved length field */			return ndr_pull_error(ndr, NDR_ERR_STRING,					      "BAD NBT NAME component");		}		if (*offset + len + 2 > ndr->data_size) {			return ndr_pull_error(ndr, NDR_ERR_STRING,					      "BAD NBT NAME component");		}		*component = (uint8_t*)talloc_strndup(ndr, (const char *)&ndr->data[1 + *offset], len);		NDR_ERR_HAVE_NO_MEMORY(*component);		*offset += len + 1;		*max_offset = MAX(*max_offset, *offset);		return NDR_ERR_SUCCESS;	}	/* too many pointers */	return ndr_pull_error(ndr, NDR_ERR_STRING, "BAD NBT NAME component");}/**  pull a nbt_string from the wire*/_PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s){	uint32_t offset = ndr->offset;	uint32_t max_offset = offset;	unsigned num_components;	char *name;	if (!(ndr_flags & NDR_SCALARS)) {		return NDR_ERR_SUCCESS;	}	name = NULL;	/* break up name into a list of components */	for (num_components=0;num_components<MAX_COMPONENTS;num_components++) {		uint8_t *component;		NDR_CHECK(ndr_pull_component(ndr, &component, &offset, &max_offset));		if (component == NULL) break;		if (name) {			name = talloc_asprintf_append_buffer(name, ".%s", component);			NDR_ERR_HAVE_NO_MEMORY(name);		} else {			name = (char *)component;		}	}	if (num_components == MAX_COMPONENTS) {		return ndr_pull_error(ndr, NDR_ERR_STRING,				      "BAD NBT NAME too many components");	}	if (num_components == 0) {		name = talloc_strdup(ndr, "");		NDR_ERR_HAVE_NO_MEMORY(name);	}	(*s) = name;	ndr->offset = max_offset;	return NDR_ERR_SUCCESS;}/**  push a nbt string to the wire*/_PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s){	if (!(ndr_flags & NDR_SCALARS)) {		return NDR_ERR_SUCCESS;	}	while (s && *s) {		enum ndr_err_code ndr_err;		char *compname;		size_t complen;		uint32_t offset;		/* see if we have pushed the remaing string allready,		 * if so we use a label pointer to this string		 */		ndr_err = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, false);		if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {			uint8_t b[2];						if (offset > 0x3FFF) {				return ndr_push_error(ndr, NDR_ERR_STRING,						      "offset for nbt string label pointer %u[%08X] > 0x00003FFF",						      offset, offset);			}			b[0] = 0xC0 | (offset>>8);			b[1] = (offset & 0xFF);			return ndr_push_bytes(ndr, b, 2);		}		complen = strcspn(s, ".");		/* we need to make sure the length fits into 6 bytes */		if (complen >= 0x3F) {			return ndr_push_error(ndr, NDR_ERR_STRING,					      "component length %u[%08X] > 0x00003F",					      (unsigned)complen, (unsigned)complen);		}		compname = talloc_asprintf(ndr, "%c%*.*s",						(unsigned char)complen,						(unsigned char)complen,						(unsigned char)complen, s);		NDR_ERR_HAVE_NO_MEMORY(compname);		/* remember the current componemt + the rest of the string		 * so it can be reused later		 */		NDR_CHECK(ndr_token_store(ndr, &ndr->nbt_string_list, s, ndr->offset));		/* push just this component into the blob */		NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname, complen+1));		talloc_free(compname);		s += complen;		if (*s == '.') s++;	}	/* if we reach the end of the string and have pushed the last component	 * without using a label pointer, we need to terminate the string	 */	return ndr_push_bytes(ndr, (const uint8_t *)"", 1);}/*  decompress a 'compressed' name component */static bool decompress_name(char *name, enum nbt_name_type *type){	int i;	for (i=0;name[2*i];i++) {		uint8_t c1 = name[2*i];		uint8_t c2 = name[1+(2*i)];		if (c1 < 'A' || c1 > 'P' ||		    c2 < 'A' || c2 > 'P') {			return false;		}		name[i] = ((c1-'A')<<4) | (c2-'A');		    	}	name[i] = 0;	if (i == 16) {		*type = (enum nbt_name_type)(name[15]);		name[15] = 0;		i--;	} else {		*type = NBT_NAME_CLIENT;	}	/* trim trailing spaces */	for (;i>0 && name[i-1]==' ';i--) {		name[i-1] = 0;	}		return true;}/*  compress a name component */static uint8_t *compress_name(TALLOC_CTX *mem_ctx, 			      const uint8_t *name, enum nbt_name_type type){	uint8_t *cname;	int i;	uint8_t pad_char;	if (strlen((const char *)name) > 15) {		return NULL;	}	cname = talloc_array(mem_ctx, uint8_t, 33);	if (cname == NULL) return NULL;	for (i=0;name[i];i++) {		cname[2*i]   = 'A' + (name[i]>>4);		cname[1+2*i] = 'A' + (name[i]&0xF);	}	if (strcmp((const char *)name, "*") == 0) {		pad_char = 0;	} else {		pad_char = ' ';	}	for (;i<15;i++) {		cname[2*i]   = 'A' + (pad_char>>4);		cname[1+2*i] = 'A' + (pad_char&0xF);	}	pad_char = type;	cname[2*i]   = 'A' + (pad_char>>4);	cname[1+2*i] = 'A' + (pad_char&0xF);	cname[32] = 0;	return cname;}/**  pull a nbt name from the wire*/_PUBLIC_ enum ndr_err_code ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r){	uint8_t *scope;	char *cname;	const char *s;	bool ok;	if (!(ndr_flags & NDR_SCALARS)) {		return NDR_ERR_SUCCESS;	}	NDR_CHECK(ndr_pull_nbt_string(ndr, ndr_flags, &s));	scope = (uint8_t *)strchr(s, '.');	if (scope) {		*scope = 0;		r->scope = talloc_strdup(ndr->current_mem_ctx, (const char *)&scope[1]);		NDR_ERR_HAVE_NO_MEMORY(r->scope);	} else {		r->scope = NULL;	}	cname = discard_const_p(char, s);	/* the first component is limited to 16 bytes in the DOS charset,	   which is 32 in the 'compressed' form */	if (strlen(cname) > 32) {		return ndr_pull_error(ndr, NDR_ERR_STRING,				      "NBT NAME cname > 32");	}	/* decompress the first component */	ok = decompress_name(cname, &r->type);	if (!ok) {		return ndr_pull_error(ndr, NDR_ERR_STRING,				      "NBT NAME failed to decompress");	}	r->name = talloc_strdup(ndr->current_mem_ctx, cname);	NDR_ERR_HAVE_NO_MEMORY(r->name);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -