Example #1
0
static uint32_t _reg_perfcount_multi_sz_from_tdb(TDB_CONTEXT *tdb,
					       int keyval,
					       char **retbuf,
					       uint32_t buffer_size)
{
	TDB_DATA kbuf, dbuf;
	char temp[PERFCOUNT_MAX_LEN] = {0};
	char *buf1 = *retbuf;
	uint32_t working_size = 0;
	DATA_BLOB name_index, name;
	bool ok;

	snprintf(temp, sizeof(temp), "%d", keyval);
	kbuf = string_tdb_data(temp);
	dbuf = tdb_fetch(tdb, kbuf);
	if(dbuf.dptr == NULL)
	{
		/* If a key isn't there, just bypass it -- this really shouldn't 
		   happen unless someone's mucking around with the tdb */
		DEBUG(3, ("_reg_perfcount_multi_sz_from_tdb: failed to find key [%s] in [%s].\n",
			  temp, tdb_name(tdb)));
		return buffer_size;
	}
	/* First encode the name_index */
	working_size = (kbuf.dsize + 1)*sizeof(uint16_t);
	buf1 = (char *)SMB_REALLOC(buf1, buffer_size + working_size);
	if(!buf1) {
		buffer_size = 0;
		return buffer_size;
	}
	ok = push_reg_sz(talloc_tos(), &name_index, (const char *)kbuf.dptr);
	if (!ok) {
		buffer_size = 0;
		return buffer_size;
	}
	memcpy(buf1+buffer_size, (char *)name_index.data, working_size);
	buffer_size += working_size;
	/* Now encode the actual name */
	working_size = (dbuf.dsize + 1)*sizeof(uint16_t);
	buf1 = (char *)SMB_REALLOC(buf1, buffer_size + working_size);
	if(!buf1) {
		buffer_size = 0;
		return buffer_size;
	}
	memset(temp, 0, sizeof(temp));
	memcpy(temp, dbuf.dptr, dbuf.dsize);
	SAFE_FREE(dbuf.dptr);
	ok = push_reg_sz(talloc_tos(), &name, temp);
	if (!ok) {
		buffer_size = 0;
		return buffer_size;
	}
	memcpy(buf1+buffer_size, (char *)name.data, working_size);
	buffer_size += working_size;

	*retbuf = buf1;

	return buffer_size;
}
Example #2
0
static struct group *nss_getgrgid(gid_t gid)
{
	NSS_STATUS (*_nss_getgrgid_r)(gid_t , struct group *, char *, 
				      size_t , int *) = find_fn("getgrgid_r");
	static struct group grp;
	static char *buf;
	static int buflen = 1000;
	NSS_STATUS status;
	
	if (!_nss_getgrgid_r)
		return NULL;

	if (!buf) 
		buf = SMB_MALLOC(buflen);

again:	
	status = _nss_getgrgid_r(gid, &grp, buf, buflen, &nss_errno);
	if (status == NSS_STATUS_TRYAGAIN) {
		buflen *= 2;
		buf = SMB_REALLOC(buf, buflen);
		if (!buf) {
			return NULL;
		}
		goto again;
	}
	if (status == NSS_STATUS_NOTFOUND) {
		return NULL;
	}
	if (status != NSS_STATUS_SUCCESS) {
		report_nss_error("getgrgid", status);
		return NULL;
	}
	return &grp;
}
Example #3
0
static struct smb_acl_t *smb_acl_to_internal(acl_t acl)
{
	struct smb_acl_t *result = SMB_MALLOC_P(struct smb_acl_t);
	int entry_id = ACL_FIRST_ENTRY;
	acl_entry_t e;
	if (result == NULL) {
		return NULL;
	}
	ZERO_STRUCTP(result);
	while (acl_get_entry(acl, entry_id, &e) == 1) {

		entry_id = ACL_NEXT_ENTRY;

		result = (struct smb_acl_t *)SMB_REALLOC(
			result, sizeof(struct smb_acl_t) +
			(sizeof(struct smb_acl_entry) * (result->count+1)));
		if (result == NULL) {
			DEBUG(0, ("SMB_REALLOC failed\n"));
			errno = ENOMEM;
			return NULL;
		}

		if (!smb_ace_to_internal(e, &result->acl[result->count])) {
			SAFE_FREE(result);
			return NULL;
		}

		result->count += 1;
	}
	return result;
}
Example #4
0
bool prs_grow(prs_struct *ps, uint32 extra_space)
{
	uint32 new_size;

	ps->grow_size = MAX(ps->grow_size, ps->data_offset + extra_space);

	if(ps->data_offset + extra_space <= ps->buffer_size)
		return True;

	/*
	 * We cannot grow the buffer if we're not reading
	 * into the prs_struct, or if we don't own the memory.
	 */

	if(UNMARSHALLING(ps) || !ps->is_dynamic) {
		DEBUG(0,("prs_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
				(unsigned int)extra_space));
		return False;
	}
	
	/*
	 * Decide how much extra space we really need.
	 */

	extra_space -= (ps->buffer_size - ps->data_offset);
	if(ps->buffer_size == 0) {

		/*
		 * Start with 128 bytes (arbitrary value), enough for small rpc
		 * requests
		 */
		new_size = MAX(128, extra_space);

		if((ps->data_p = (char *)SMB_MALLOC(new_size)) == NULL) {
			DEBUG(0,("prs_grow: Malloc failure for size %u.\n", (unsigned int)new_size));
			return False;
		}
		memset(ps->data_p, '\0', (size_t)new_size );
	} else {
		/*
		 * If the current buffer size is bigger than the space needed,
		 * just double it, else add extra_space. Always keep 64 bytes
		 * more, so that after we added a large blob we don't have to
		 * realloc immediately again.
		 */
		new_size = MAX(ps->buffer_size*2,
			       ps->buffer_size + extra_space + 64);

		if ((ps->data_p = (char *)SMB_REALLOC(ps->data_p, new_size)) == NULL) {
			DEBUG(0,("prs_grow: Realloc failure for size %u.\n",
				(unsigned int)new_size));
			return False;
		}

		memset(&ps->data_p[ps->buffer_size], '\0', (size_t)(new_size - ps->buffer_size));
	}
	ps->buffer_size = new_size;

	return True;
}
Example #5
0
bool prs_set_buffer_size(prs_struct *ps, uint32 newsize)
{
	if (newsize > ps->buffer_size)
		return prs_force_grow(ps, newsize - ps->buffer_size);

	if (newsize < ps->buffer_size) {
		ps->buffer_size = newsize;

		/* newsize == 0 acts as a free and set pointer to NULL */
		if (newsize == 0) {
			SAFE_FREE(ps->data_p);
		} else {
			ps->data_p = (char *)SMB_REALLOC(ps->data_p, newsize);

			if (ps->data_p == NULL) {
				DEBUG(0,("prs_set_buffer_size: Realloc failure for size %u.\n",
					(unsigned int)newsize));
				DEBUG(0,("prs_set_buffer_size: Reason %s\n",strerror(errno)));
				return False;
			}
		}
	}

	return True;
}
Example #6
0
void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size)
#endif
{
	struct talloc_chunk *tc;
	void *new_ptr;

	/* size zero is equivalent to free() */
	if (!t || size == 0)
		return NULL;

	/* realloc(NULL) is equavalent to malloc() */
	if (ptr == NULL)
		return TALLOC(t, size);

	for (tc=t->list; tc; tc=tc->next) {
		if (tc->ptr == ptr) {
			new_ptr = SMB_REALLOC(ptr, size);
			if (new_ptr) {
				t->total_alloc_size += (size - tc->size);
				tc->size = size;
				tc->ptr = new_ptr;
			}
			return new_ptr;
		}
	}
	return NULL;
}
Example #7
0
char *escape_ldap_string_alloc(const char *s)
{
	size_t len = strlen(s)+1;
	char *output = SMB_MALLOC(len);
	char *output_tmp;
	const char *sub;
	int i = 0;
	char *p = output;
	
	while (*s)
	{
		switch (*s)
		{
		case '*':
			sub = "\\2a";
			break;
		case '(':
			sub = "\\28";
			break;
		case ')':
			sub = "\\29";
			break;
		case '\\':
			sub = "\\5c";
			break;
		default:
			sub = NULL;
			break;
		}
		
		if (sub) {
			len = len + 3;
			output_tmp = SMB_REALLOC(output, len);
			if (!output_tmp) { 
				SAFE_FREE(output);
				return NULL;
			}
			output = output_tmp;
			
			p = &output[i];
			strncpy (p, sub, 3);
			p += 3;
			i += 3;

		} else {
			*p = *s;
			p++;
			i++;
		}
		s++;
	}
	
	*p = '\0';
	return output;
}
Example #8
0
enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
						   *state)
{
	struct winbindd_domain *domain;
	int total_entries = 0, extra_data_len = 0;
	char *ted, *extra_data = NULL;

	DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid));

	/* We need to refresh the trusted domain list as the domains may
	   have changed since we last looked.  There may be a sequence
	   number or something we should use but I haven't found it yet. */

	if (!init_domain_list()) {
		DEBUG(1, ("winbindd_list_trusted_domains: could not "
			  "refresh trusted domain list\n"));
		return WINBINDD_ERROR;
	}

	for(domain = domain_list(); domain; domain = domain->next) {

		/* Skip own domain */

		if (domain->primary) continue;

		/* Add domain to list */

		total_entries++;
		ted = SMB_REALLOC(extra_data, sizeof(fstring) * 
                              total_entries);

		if (!ted) {
			DEBUG(0,("winbindd_list_trusted_domains: failed to enlarge buffer!\n"));
			SAFE_FREE(extra_data);
			return WINBINDD_ERROR;
		} else 
                        extra_data = ted;

		memcpy(&extra_data[extra_data_len], domain->name,
		       strlen(domain->name));

		extra_data_len  += strlen(domain->name);
		extra_data[extra_data_len++] = ',';
	}

	if (extra_data) {
		if (extra_data_len > 1) 
                        extra_data[extra_data_len - 1] = '\0';
		state->response.extra_data = extra_data;
		state->response.length += extra_data_len;
	}

	return WINBINDD_OK;
}
Example #9
0
/* 
 * convert either the access or the default part of a 
 * soaris acl to the SMB_ACL format.
 */
static SMB_ACL_T solaris_acl_to_smb_acl(SOLARIS_ACL_T solaris_acl, int count, 
					SMB_ACL_TYPE_T type)
{
	SMB_ACL_T result;
	int i;

	if ((result = sys_acl_init(0)) == NULL) {
		DEBUG(10, ("error allocating memory for SMB_ACL\n"));
		goto fail;
	}
	for (i = 0; i < count; i++) {
		SMB_ACL_ENTRY_T smb_entry;
		SMB_ACL_PERM_T smb_perm;
		
		if (!_IS_OF_TYPE(solaris_acl[i], type)) {
			continue;
		}
		result = SMB_REALLOC(result, 
				     sizeof(struct smb_acl_t) +
				     (sizeof(struct smb_acl_entry) *
				      (result->count + 1)));
		if (result == NULL) {
			DEBUG(10, ("error reallocating memory for SMB_ACL\n"));
			goto fail;
		}
		smb_entry = &result->acl[result->count];
		if (sys_acl_set_tag_type(smb_entry,
					 solaris_tag_to_smb_tag(solaris_acl[i].a_type)) != 0)
		{
			DEBUG(10, ("invalid tag type given: 0x%04x\n",
				   solaris_acl[i].a_type));
			goto fail;
		}
		/* intentionally not checking return code here: */
		sys_acl_set_qualifier(smb_entry, (void *)&solaris_acl[i].a_id);
		smb_perm = solaris_perm_to_smb_perm(solaris_acl[i].a_perm);
		if (sys_acl_set_permset(smb_entry, &smb_perm) != 0) {
			DEBUG(10, ("invalid permset given: %d\n", 
				   solaris_acl[i].a_perm));
			goto fail;
		}
		result->count += 1;
	}
	goto done;
	
 fail:
	SAFE_FREE(result);
 done:
	DEBUG(10, ("solaris_acl_to_smb_acl %s\n",
		   ((result == NULL) ? "failed" : "succeeded")));
	return result;
}
Example #10
0
/* write to the ASN1 buffer, advancing the buffer pointer */
BOOL asn1_write(ASN1_DATA *data, const void *p, int len)
{
	if (data->has_error) return False;
	if (data->length < data->ofs+len) {
		data->data = SMB_REALLOC(data->data, data->ofs+len);
		if (!data->data) {
			data->has_error = True;
			return False;
		}
		data->length = data->ofs+len;
	}
	memcpy(data->data + data->ofs, p, len);
	data->ofs += len;
	return True;
}
Example #11
0
uint32_t reg_perfcount_get_counter_names(uint32_t base_index, char **retbuf)
{
	char *buf1 = NULL;
	uint32_t buffer_size = 0;
	TDB_CONTEXT *names;
	char *fname;
	int i;

	if (base_index == 0) {
		return 0;
	}

	fname = counters_directory(NAMES_DB);
	if (fname == NULL) {
		return 0;
	}

	names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);

	if (names == NULL) {
		DEBUG(1, ("reg_perfcount_get_counter_names: unable to open [%s].\n", fname));
		TALLOC_FREE(fname);
		return 0;
	}
	TALLOC_FREE(fname);

	buffer_size = _reg_perfcount_multi_sz_from_tdb(names, 1, retbuf, buffer_size);

	for(i = 1; i <= base_index; i++)
	{
		buffer_size = _reg_perfcount_multi_sz_from_tdb(names, i*2, retbuf, buffer_size);
	}
	tdb_close(names);

	/* Now terminate the MULTI_SZ with a double unicode NULL */
	buf1 = *retbuf;
	buf1 = (char *)SMB_REALLOC(buf1, buffer_size + 2);
	if(!buf1) {
		buffer_size = 0;
	} else {
		buf1[buffer_size++] = '\0';
		buf1[buffer_size++] = '\0';
	}

	*retbuf=buf1;

	return buffer_size;
}
Example #12
0
char *file_pload(char *syscmd, size_t *size)
{
    int fd, n;
    char *p;
    pstring buf;
    size_t total;

    fd = sys_popen(syscmd);
    if (fd == -1) {
        return NULL;
    }

    p = NULL;
    total = 0;

    while ((n = read(fd, buf, sizeof(buf))) > 0) {
        p = (char *)SMB_REALLOC(p, total + n + 1);
        if (!p) {
            DEBUG(0,("file_pload: failed to expand buffer!\n"));
            close(fd);
            return NULL;
        }
        memcpy(p+total, buf, n);
        total += n;
    }

    if (p) {
        p[total] = 0;
    }

    /* FIXME: Perhaps ought to check that the command completed
     * successfully (returned 0); if not the data may be
     * truncated. */
    sys_pclose(fd);

    if (size) {
        *size = total;
    }

    return p;
}
Example #13
0
bool prs_force_grow(prs_struct *ps, uint32 extra_space)
{
	uint32 new_size = ps->buffer_size + extra_space;

	if(!UNMARSHALLING(ps) || !ps->is_dynamic) {
		DEBUG(0,("prs_force_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
				(unsigned int)extra_space));
		return False;
	}

	if((ps->data_p = (char *)SMB_REALLOC(ps->data_p, new_size)) == NULL) {
		DEBUG(0,("prs_force_grow: Realloc failure for size %u.\n",
			(unsigned int)new_size));
		return False;
	}

	memset(&ps->data_p[ps->buffer_size], '\0', (size_t)(new_size - ps->buffer_size));

	ps->buffer_size = new_size;

	return True;
}
Example #14
0
void add_session_user(const char *user)
{
	fstring suser;
	struct passwd *passwd;

	if (!(passwd = Get_Pwnam(user)))
		return;

	fstrcpy(suser,passwd->pw_name);

	if(!*suser)
		return;

	if( session_userlist && in_list(suser,session_userlist,False) )
		return;

	if( !session_userlist || (strlen(suser) + strlen(session_userlist) + 2 >= len_session_userlist) ) {
		char *newlist;

		if (len_session_userlist > 128 * PSTRING_LEN) {
			DEBUG(3,("add_session_user: session userlist already too large.\n"));
			return;
		}
		newlist = SMB_REALLOC( session_userlist, len_session_userlist + PSTRING_LEN );
		if( newlist == NULL ) {
			DEBUG(1,("Unable to resize session_userlist\n"));
			return;
		}
		if (!session_userlist) {
			*newlist = '\0';
		}
		session_userlist = newlist;
		len_session_userlist += PSTRING_LEN;
	}

	safe_strcat(session_userlist," ",len_session_userlist-1);
	safe_strcat(session_userlist,suser,len_session_userlist-1);
}
Example #15
0
size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
			       void const *src, size_t srclen, void *dst, BOOL allow_bad_conv)
{
	size_t i_len, o_len, destlen = (srclen * 3) / 2;
	size_t retval;
	const char *inbuf = (const char *)src;
	char *outbuf = NULL, *ob = NULL;
	smb_iconv_t descriptor;
	void **dest = (void **)dst;

	*dest = NULL;

	if (src == NULL || srclen == (size_t)-1)
		return (size_t)-1;
	if (srclen == 0)
		return 0;

	lazy_initialize_conv();

	descriptor = conv_handles[from][to];

	if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
		if (!conv_silent)
			DEBUG(0,("convert_string_allocate: Conversion not supported.\n"));
		return (size_t)-1;
	}

  convert:

	/* +2 is for ucs2 null termination. */
	if ((destlen*2)+2 < destlen) {
		/* wrapped ! abort. */
		if (!conv_silent)
			DEBUG(0, ("convert_string_allocate: destlen wrapped !\n"));
		if (!ctx)
			SAFE_FREE(outbuf);
		return (size_t)-1;
	} else {
		destlen = destlen * 2;
	}

	/* +2 is for ucs2 null termination. */
	if (ctx) {
		ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2);
	} else {
		ob = (char *)SMB_REALLOC(ob, destlen + 2);
	}

	if (!ob) {
		DEBUG(0, ("convert_string_allocate: realloc failed!\n"));
		return (size_t)-1;
	}
	outbuf = ob;
	i_len = srclen;
	o_len = destlen;

 again:

	retval = smb_iconv(descriptor,
			   &inbuf, &i_len,
			   &outbuf, &o_len);
	if(retval == (size_t)-1) 		{
	    	const char *reason="unknown error";
		switch(errno) {
			case EINVAL:
				reason="Incomplete multibyte sequence";
				if (!conv_silent)
					DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
				if (allow_bad_conv)
					goto use_as_is;
				break;
			case E2BIG:
				goto convert;		
			case EILSEQ:
				reason="Illegal multibyte sequence";
				if (!conv_silent)
					DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf));
				if (allow_bad_conv)
					goto use_as_is;
				break;
		}
		if (!conv_silent)
			DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
		/* smb_panic(reason); */
		return (size_t)-1;
	}

  out:

	destlen = destlen - o_len;
	if (ctx) {
		/* We're shrinking here so we know the +2 is safe from wrap. */
		ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2);
	} else {
		ob = (char *)SMB_REALLOC(ob,destlen + 2);
	}

	if (destlen && !ob) {
		DEBUG(0, ("convert_string_allocate: out of memory!\n"));
		return (size_t)-1;
	}

	*dest = ob;

	/* Must ucs2 null terminate in the extra space we allocated. */
	ob[destlen] = '\0';
	ob[destlen+1] = '\0';

	return destlen;

 use_as_is:

	/* 
	 * Conversion not supported. This is actually an error, but there are so
	 * many misconfigured iconv systems and smb.conf's out there we can't just
	 * fail. Do a very bad conversion instead.... JRA.
	 */

	{
		if (o_len == 0 || i_len == 0)
			goto out;

		if (((from == CH_UTF16LE)||(from == CH_UTF16BE)) &&
				((to != CH_UTF16LE)||(to != CH_UTF16BE))) {
			/* Can't convert from utf16 any endian to multibyte.
			   Replace with the default fail char.
			*/

			if (i_len < 2)
				goto out;

			if (i_len >= 2) {
				*outbuf = lp_failed_convert_char();

				outbuf++;
				o_len--;

				inbuf += 2;
				i_len -= 2;
			}

			if (o_len == 0 || i_len == 0)
				goto out;

			/* Keep trying with the next char... */
			goto again;

		} else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
			/* Can't convert to UTF16LE - just widen by adding the
			   default fail char then zero.
			*/
			if (o_len < 2)
				goto out;

			outbuf[0] = lp_failed_convert_char();
			outbuf[1] = '\0';

			inbuf++;
			i_len--;

			outbuf += 2;
			o_len -= 2;

			if (o_len == 0 || i_len == 0)
				goto out;

			/* Keep trying with the next char... */
			goto again;

		} else if (from != CH_UTF16LE && from != CH_UTF16BE &&
				to != CH_UTF16LE && to != CH_UTF16BE) {
			/* Failed multibyte to multibyte. Just copy the default fail char and
			   try again. */
			outbuf[0] = lp_failed_convert_char();

			inbuf++;
			i_len--;

			outbuf++;
			o_len--;

			if (o_len == 0 || i_len == 0)
				goto out;

			/* Keep trying with the next char... */
			goto again;

		} else {
			/* Keep compiler happy.... */
			goto out;
		}
	}
}
Example #16
0
int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, 
		 void (*fn)(const char *, file_info *, const char *, void *), void *state)
{
	char *p;
	int received = 0;
	BOOL first = True;
	char status[21];
	int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE;
	int num_received = 0;
	int i;
	char *dirlist = NULL;
	pstring mask;
	
	ZERO_ARRAY(status);

	pstrcpy(mask,Mask);
  
	while (1) {
		memset(cli->outbuf,'\0',smb_size);
		memset(cli->inbuf,'\0',smb_size);

		set_message(cli->outbuf,2,0,True);

		SCVAL(cli->outbuf,smb_com,SMBsearch);

		SSVAL(cli->outbuf,smb_tid,cli->cnum);
		cli_setup_packet(cli);

		SSVAL(cli->outbuf,smb_vwv0,num_asked);
		SSVAL(cli->outbuf,smb_vwv1,attribute);
  
		p = smb_buf(cli->outbuf);
		*p++ = 4;
      
		p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE);
		*p++ = 5;
		if (first) {
			SSVAL(p,0,0);
			p += 2;
		} else {
			SSVAL(p,0,21);
			p += 2;
			memcpy(p,status,21);
			p += 21;
		}

		cli_setup_bcc(cli, p);
		cli_send_smb(cli);
		if (!cli_receive_smb(cli)) break;

		received = SVAL(cli->inbuf,smb_vwv0);
		if (received <= 0) break;

		first = False;

		dirlist = (char *)SMB_REALLOC(
			dirlist,(num_received + received)*DIR_STRUCT_SIZE);
		if (!dirlist) {
			DEBUG(0,("cli_list_old: failed to expand dirlist"));
			return 0;
		}

		p = smb_buf(cli->inbuf) + 3;

		memcpy(dirlist+num_received*DIR_STRUCT_SIZE,
		       p,received*DIR_STRUCT_SIZE);
		
		memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21);
		
		num_received += received;
		
		if (cli_is_error(cli)) break;
	}

	if (!first) {
		memset(cli->outbuf,'\0',smb_size);
		memset(cli->inbuf,'\0',smb_size);

		set_message(cli->outbuf,2,0,True);
		SCVAL(cli->outbuf,smb_com,SMBfclose);
		SSVAL(cli->outbuf,smb_tid,cli->cnum);
		cli_setup_packet(cli);

		SSVAL(cli->outbuf, smb_vwv0, 0); /* find count? */
		SSVAL(cli->outbuf, smb_vwv1, attribute);

		p = smb_buf(cli->outbuf);
		*p++ = 4;
		fstrcpy(p, "");
		p += strlen(p) + 1;
		*p++ = 5;
		SSVAL(p, 0, 21);
		p += 2;
		memcpy(p,status,21);
		p += 21;
		
		cli_setup_bcc(cli, p);
		cli_send_smb(cli);
		if (!cli_receive_smb(cli)) {
			DEBUG(0,("Error closing search: %s\n",cli_errstr(cli)));
		}
	}

	for (p=dirlist,i=0;i<num_received;i++) {
		file_info finfo;
		p += interpret_short_filename(cli, p,&finfo);
		fn("\\", &finfo, Mask, state);
	}

	SAFE_FREE(dirlist);
	return(num_received);
}
Example #17
0
int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, 
		 void (*fn)(const char *, file_info *, const char *, void *), void *state)
{
#if 1
	int max_matches = 1366; /* Match W2k - was 512. */
#else
	int max_matches = 512;
#endif
	int info_level;
	char *p, *p2;
	pstring mask;
	file_info finfo;
	int i;
	char *dirlist = NULL;
	int dirlist_len = 0;
	int total_received = -1;
	BOOL First = True;
	int ff_searchcount=0;
	int ff_eos=0;
	int ff_dir_handle=0;
	int loop_count = 0;
	char *rparam=NULL, *rdata=NULL;
	unsigned int param_len, data_len;	
	uint16 setup;
	pstring param;
	const char *mnt;
	uint32 resume_key = 0;
	uint32 last_name_raw_len = 0;
	DATA_BLOB last_name_raw = data_blob(NULL, 2*sizeof(pstring));

	/* NT uses 260, OS/2 uses 2. Both accept 1. */
	info_level = (cli->capabilities&CAP_NT_SMBS)?260:1;
	
	pstrcpy(mask,Mask);
	
	while (ff_eos == 0) {
		loop_count++;
		if (loop_count > 200) {
			DEBUG(0,("Error: Looping in FIND_NEXT??\n"));
			break;
		}

		if (First) {
			setup = TRANSACT2_FINDFIRST;
			SSVAL(param,0,attribute); /* attribute */
			SSVAL(param,2,max_matches); /* max count */
			SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END));	/* resume required + close on end */
			SSVAL(param,6,info_level); 
			SIVAL(param,8,0);
			p = param+12;
			p += clistr_push(cli, param+12, mask, sizeof(param)-12, 
					 STR_TERMINATE);
		} else {
			setup = TRANSACT2_FINDNEXT;
			SSVAL(param,0,ff_dir_handle);
			SSVAL(param,2,max_matches); /* max count */
			SSVAL(param,4,info_level); 
			/* For W2K servers serving out FAT filesystems we *must* set the
			   resume key. If it's not FAT then it's returned as zero. */
			SIVAL(param,6,resume_key); /* ff_resume_key */
			/* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren
			   can miss filenames. Use last filename continue instead. JRA */
			SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END));	/* resume required + close on end */
			p = param+12;
			if (last_name_raw_len && (last_name_raw_len < (sizeof(param)-12))) {
				memcpy(p, last_name_raw.data, last_name_raw_len);
				p += last_name_raw_len;
			} else {
				p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE);
			}
		}

		param_len = PTR_DIFF(p, param);

		if (!cli_send_trans(cli, SMBtrans2, 
				    NULL,                   /* Name */
				    -1, 0,                  /* fid, flags */
				    &setup, 1, 0,           /* setup, length, max */
				    param, param_len, 10,   /* param, length, max */
				    NULL, 0, 
#if 0
				    /* w2k value. */
				    MIN(16384,cli->max_xmit) /* data, length, max. */
#else
				    cli->max_xmit	    /* data, length, max. */
#endif
				    )) {
			break;
		}

		if (!cli_receive_trans(cli, SMBtrans2, 
				       &rparam, &param_len,
				       &rdata, &data_len) &&
                    cli_is_dos_error(cli)) {
			/* We need to work around a Win95 bug - sometimes
			   it gives ERRSRV/ERRerror temprarily */
			uint8 eclass;
			uint32 ecode;

			SAFE_FREE(rdata);
			SAFE_FREE(rparam);

			cli_dos_error(cli, &eclass, &ecode);

			/*
			 * OS/2 might return "no more files",
			 * which just tells us, that searchcount is zero
			 * in this search.
			 * Guenter Kukkukk <*****@*****.**>
			 */

			if (eclass == ERRDOS && ecode == ERRnofiles) {
				ff_searchcount = 0;
				cli_reset_error(cli);
				break;
			}

			if (eclass != ERRSRV || ecode != ERRerror)
				break;
			smb_msleep(100);
			continue;
		}

                if (cli_is_error(cli) || !rdata || !rparam) {
			SAFE_FREE(rdata);
			SAFE_FREE(rparam);
			break;
		}

		if (total_received == -1)
			total_received = 0;

		/* parse out some important return info */
		p = rparam;
		if (First) {
			ff_dir_handle = SVAL(p,0);
			ff_searchcount = SVAL(p,2);
			ff_eos = SVAL(p,4);
		} else {
			ff_searchcount = SVAL(p,0);
			ff_eos = SVAL(p,2);
		}

		if (ff_searchcount == 0) {
			SAFE_FREE(rdata);
			SAFE_FREE(rparam);
			break;
		}

		/* point to the data bytes */
		p = rdata;

		/* we might need the lastname for continuations */
		for (p2=p,i=0;i<ff_searchcount;i++) {
			if ((info_level == 260) && (i == ff_searchcount-1)) {
				/* Last entry - fixup the last offset length. */
				SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2));
			}
			p2 += interpret_long_filename(cli,info_level,p2,&finfo,
							&resume_key,&last_name_raw,&last_name_raw_len);

			if (!First && *mask && strcsequal(finfo.name, mask)) {
				DEBUG(0,("Error: Looping in FIND_NEXT as name %s has already been seen?\n",
					finfo.name));
				ff_eos = 1;
				break;
			}
		}

		if (ff_searchcount > 0) {
			pstrcpy(mask, finfo.name);
		} else {
			pstrcpy(mask,"");
		}

		/* grab the data for later use */
		/* and add them to the dirlist pool */
		dirlist = (char *)SMB_REALLOC(dirlist,dirlist_len + data_len);

		if (!dirlist) {
			DEBUG(0,("cli_list_new: Failed to expand dirlist\n"));
			SAFE_FREE(rdata);
			SAFE_FREE(rparam);
			break;
		}

		memcpy(dirlist+dirlist_len,p,data_len);
		dirlist_len += data_len;

		total_received += ff_searchcount;

		SAFE_FREE(rdata);
		SAFE_FREE(rparam);

		DEBUG(3,("received %d entries (eos=%d)\n",
			 ff_searchcount,ff_eos));

		if (ff_searchcount > 0)
			loop_count = 0;

		First = False;
	}

	mnt = cli_cm_get_mntpoint( cli );

        /* see if the server disconnected or the connection otherwise failed */
        if (cli_is_error(cli)) {
                total_received = -1;
        } else {
                /* no connection problem.  let user function add each entry */
                for (p=dirlist,i=0;i<total_received;i++) {
                        p += interpret_long_filename(cli, info_level, p,
                                                     &finfo,NULL,NULL,NULL);
                        fn( mnt,&finfo, Mask, state );
                }
        }

	/* free up the dirlist buffer and last name raw blob */
	SAFE_FREE(dirlist);
	data_blob_free(&last_name_raw);
	return(total_received);
}
Example #18
0
static void fill_in_driver_values( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3, REGVAL_CTR *values )
{
	char *buffer = NULL;
	int buffer_size = 0;
	int i, length;
	char *filename;
	UNISTR2	data;
	
	filename = dos_basename( info3->driverpath );
	init_unistr2( &data, filename, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Driver", REG_SZ, (char*)data.buffer, 
		data.uni_str_len*sizeof(uint16) );
	
	filename = dos_basename( info3->configfile );
	init_unistr2( &data, filename, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Configuration File", REG_SZ, (char*)data.buffer, 
		data.uni_str_len*sizeof(uint16) );
	
	filename = dos_basename( info3->datafile );
	init_unistr2( &data, filename, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Data File", REG_SZ, (char*)data.buffer, 
		data.uni_str_len*sizeof(uint16) );
	
	filename = dos_basename( info3->helpfile );
	init_unistr2( &data, filename, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Help File", REG_SZ, (char*)data.buffer, 
		data.uni_str_len*sizeof(uint16) );
	
	init_unistr2( &data, info3->defaultdatatype, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Data Type", REG_SZ, (char*)data.buffer, 
		data.uni_str_len*sizeof(uint16) );
	
	regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&info3->cversion, 
		sizeof(info3->cversion) );
	
	if ( info3->dependentfiles ) {
		/* place the list of dependent files in a single 
		   character buffer, separating each file name by
		   a NULL */
		   
		for ( i=0; strcmp(info3->dependentfiles[i], ""); i++ ) {
			/* strip the path to only the file's base name */
		
			filename = dos_basename( info3->dependentfiles[i] );
			
			length = strlen(filename);
		
			buffer = (char *)SMB_REALLOC( buffer, buffer_size + (length + 1)*sizeof(uint16) );
			if ( !buffer ) {
				break;
			}
			
			init_unistr2( &data, filename, UNI_STR_TERMINATE);
			memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
		
			buffer_size += (length + 1)*sizeof(uint16);
		}
		
		/* terminated by double NULL.  Add the final one here */
		
		buffer = (char *)SMB_REALLOC( buffer, buffer_size + 2 );
		if ( !buffer ) {
			buffer_size = 0;
		} else {
			buffer[buffer_size++] = '\0';
			buffer[buffer_size++] = '\0';
		}
	}
	
	regval_ctr_addvalue( values, "Dependent Files",    REG_MULTI_SZ, buffer, buffer_size );
		
	SAFE_FREE( buffer );
	
	return;
}
Example #19
0
char *fgets_slash(char *s2,int maxlen,XFILE *f)
{
    char *s=s2;
    int len = 0;
    int c;
    BOOL start_of_line = True;

    if (x_feof(f)) {
        return(NULL);
    }

    if (maxlen <2) {
        return(NULL);
    }

    if (!s2) {
        maxlen = MIN(maxlen,8);
        s = (char *)SMB_MALLOC(maxlen);
    }

    if (!s) {
        return(NULL);
    }

    *s = 0;

    while (len < maxlen-1) {
        c = x_getc(f);
        switch (c) {
        case '\r':
            break;
        case '\n':
            while (len > 0 && s[len-1] == ' ') {
                s[--len] = 0;
            }
            if (len > 0 && s[len-1] == '\\') {
                s[--len] = 0;
                start_of_line = True;
                break;
            }
            return(s);
        case EOF:
            if (len <= 0 && !s2)  {
                SAFE_FREE(s);
            }
            return(len>0?s:NULL);
        case ' ':
            if (start_of_line) {
                break;
            }
        default:
            start_of_line = False;
            s[len++] = c;
            s[len] = 0;
        }

        if (!s2 && len > maxlen-3) {
            maxlen *= 2;
            s = (char *)SMB_REALLOC(s,maxlen);
            if (!s) {
                DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
                return(NULL);
            }
        }
    }
    return(s);
}
Example #20
0
bool cli_receive_nt_trans(struct cli_state *cli,
			  char **param, unsigned int *param_len,
			  char **data, unsigned int *data_len)
{
	unsigned int total_data=0;
	unsigned int total_param=0;
	unsigned int this_data,this_param;
	uint8 eclass;
	uint32 ecode;
	bool ret = False;
	uint16_t mid;

	*data_len = *param_len = 0;

	mid = SVAL(cli->outbuf,smb_mid);

	if (!cli_receive_smb(cli)) {
		cli_state_seqnum_remove(cli, mid);
		return False;
	}

	show_msg(cli->inbuf);

	/* sanity check */
	if (CVAL(cli->inbuf,smb_com) != SMBnttrans) {
		DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n",
			 CVAL(cli->inbuf,smb_com)));
		cli_state_seqnum_remove(cli, mid);
		return(False);
	}

	/*
	 * An NT RPC pipe call can return ERRDOS, ERRmoredata
	 * to a trans call. This is not an error and should not
	 * be treated as such.
	 */
	if (cli_is_dos_error(cli)) {
                cli_dos_error(cli, &eclass, &ecode);
		if (!(eclass == ERRDOS && ecode == ERRmoredata)) {
			goto out;
		}
	}

	/*
	 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
	 */
	if (cli_is_nt_error(cli)) {
		if (!NT_STATUS_EQUAL(cli_nt_error(cli),
				     NT_STATUS_BUFFER_TOO_SMALL)) {
			goto out;
		}
	}

	/* parse out the lengths */
	total_data = IVAL(cli->inbuf,smb_ntr_TotalDataCount);
	total_param = IVAL(cli->inbuf,smb_ntr_TotalParameterCount);
	/* Only allow 16 megs. */
	if (total_param > 16*1024*1024) {
		DEBUG(0,("cli_receive_nt_trans: param buffer too large %d\n",
					total_param));
		goto out;
	}
	if (total_data > 16*1024*1024) {
		DEBUG(0,("cli_receive_nt_trans: data buffer too large %d\n",
					total_data));
		goto out;
	}

	/* allocate it */
	if (total_data) {
		/* We know adding 2 is safe as total_data is less
		 * than 16mb (above). */
		*data = (char *)SMB_REALLOC(*data,total_data+2);
		if (!(*data)) {
			DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data));
			goto out;
		}
	}

	if (total_param) {
		/* We know adding 2 is safe as total_param is less
		 * than 16mb (above). */
		*param = (char *)SMB_REALLOC(*param,total_param+2);
		if (!(*param)) {
			DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param));
			goto out;
		}
	}

	while (1)  {
		this_data = SVAL(cli->inbuf,smb_ntr_DataCount);
		this_param = SVAL(cli->inbuf,smb_ntr_ParameterCount);

		if (this_data + *data_len > total_data ||
		    this_param + *param_len > total_param) {
			DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
			goto out;
		}

		if (this_data + *data_len < this_data ||
				this_data + *data_len < *data_len ||
				this_param + *param_len < this_param ||
				this_param + *param_len < *param_len) {
			DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
			goto out;
		}

		if (this_data) {
			unsigned int data_offset_out = SVAL(cli->inbuf,smb_ntr_DataDisplacement);
			unsigned int data_offset_in = SVAL(cli->inbuf,smb_ntr_DataOffset);

			if (data_offset_out > total_data ||
					data_offset_out + this_data > total_data ||
					data_offset_out + this_data < data_offset_out ||
					data_offset_out + this_data < this_data) {
				DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
				goto out;
			}
			if (data_offset_in > cli->bufsize ||
					data_offset_in + this_data >  cli->bufsize ||
					data_offset_in + this_data < data_offset_in ||
					data_offset_in + this_data < this_data) {
				DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
				goto out;
			}

			memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data);
		}

		if (this_param) {
			unsigned int param_offset_out = SVAL(cli->inbuf,smb_ntr_ParameterDisplacement);
			unsigned int param_offset_in = SVAL(cli->inbuf,smb_ntr_ParameterOffset);

			if (param_offset_out > total_param ||
					param_offset_out + this_param > total_param ||
					param_offset_out + this_param < param_offset_out ||
					param_offset_out + this_param < this_param) {
				DEBUG(1,("Param overflow in cli_receive_nt_trans\n"));
				goto out;
			}
			if (param_offset_in > cli->bufsize ||
					param_offset_in + this_param >  cli->bufsize ||
					param_offset_in + this_param < param_offset_in ||
					param_offset_in + this_param < this_param) {
				DEBUG(1,("Param overflow in cli_receive_nt_trans\n"));
				goto out;
			}

			memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param);
		}

		*data_len += this_data;
		*param_len += this_param;

		if (total_data <= *data_len && total_param <= *param_len) {
			ret = True;
			break;
		}

		if (!cli_receive_smb(cli)) {
			goto out;
		}

		show_msg(cli->inbuf);

		/* sanity check */
		if (CVAL(cli->inbuf,smb_com) != SMBnttrans) {
			DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n",
				 CVAL(cli->inbuf,smb_com)));
			goto out;
		}
		if (cli_is_dos_error(cli)) {
                        cli_dos_error(cli, &eclass, &ecode);
			if(!(eclass == ERRDOS && ecode == ERRmoredata)) {
				goto out;
			}
		}
		/*
		 * Likewise for NT_STATUS_BUFFER_TOO_SMALL
		 */
		if (cli_is_nt_error(cli)) {
			if (!NT_STATUS_EQUAL(cli_nt_error(cli),
					     NT_STATUS_BUFFER_TOO_SMALL)) {
				goto out;
			}
		}

		/* parse out the total lengths again - they can shrink! */
		if (IVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data)
			total_data = IVAL(cli->inbuf,smb_ntr_TotalDataCount);
		if (IVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param)
			total_param = IVAL(cli->inbuf,smb_ntr_TotalParameterCount);

		if (total_data <= *data_len && total_param <= *param_len) {
			ret = True;
			break;
		}
	}

  out:

	cli_state_seqnum_remove(cli, mid);

	if (ret) {
		/* Ensure the last 2 bytes of param and data are 2 null
		 * bytes. These are malloc'ed, but not included in any
		 * length counts. This allows cli_XX string reading functions
		 * to safely null terminate. */
		if (total_data) {
			SSVAL(*data,total_data,0);
		}
		if (total_param) {
			SSVAL(*param,total_param,0);
		}
	}

	return ret;
}
Example #21
0
bool cli_receive_trans(struct cli_state *cli,int trans,
                              char **param, unsigned int *param_len,
                              char **data, unsigned int *data_len)
{
	unsigned int total_data=0;
	unsigned int total_param=0;
	unsigned int this_data,this_param;
	NTSTATUS status;
	bool ret = False;
	uint16_t mid;

	*data_len = *param_len = 0;

	mid = SVAL(cli->outbuf,smb_mid);

	if (!cli_receive_smb(cli)) {
		cli_state_seqnum_remove(cli, mid);
		return False;
	}

	show_msg(cli->inbuf);

	/* sanity check */
	if (CVAL(cli->inbuf,smb_com) != trans) {
		DEBUG(0,("Expected %s response, got command 0x%02x\n",
			 trans==SMBtrans?"SMBtrans":"SMBtrans2",
			 CVAL(cli->inbuf,smb_com)));
		cli_state_seqnum_remove(cli, mid);
		return False;
	}

	/*
	 * An NT RPC pipe call can return ERRDOS, ERRmoredata
	 * to a trans call. This is not an error and should not
	 * be treated as such. Note that STATUS_NO_MORE_FILES is
	 * returned when a trans2 findfirst/next finishes.
	 * When setting up an encrypted transport we can also
	 * see NT_STATUS_MORE_PROCESSING_REQUIRED here.
         *
         * Vista returns NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT if the folder
         * "<share>/Users/All Users" is enumerated.  This is a special pseudo
         * folder, and the response does not have parameters (nor a parameter
         * length).
	 */
	status = cli_nt_error(cli);

	if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
		if (NT_STATUS_IS_ERR(status) ||
                    NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES) ||
                    NT_STATUS_EQUAL(status,NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT)) {
			goto out;
		}
	}

	/* parse out the lengths */
	total_data = SVAL(cli->inbuf,smb_tdrcnt);
	total_param = SVAL(cli->inbuf,smb_tprcnt);

	/* allocate it */
	if (total_data!=0) {
		/* We know adding 2 is safe as total_data is an
		 * SVAL <= 0xFFFF. */
		*data = (char *)SMB_REALLOC(*data,total_data+2);
		if (!(*data)) {
			DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n"));
			goto out;
		}
	}

	if (total_param!=0) {
		/* We know adding 2 is safe as total_param is an
		 * SVAL <= 0xFFFF. */
		*param = (char *)SMB_REALLOC(*param,total_param+2);
		if (!(*param)) {
			DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n"));
			goto out;
		}
	}

	for (;;)  {
		this_data = SVAL(cli->inbuf,smb_drcnt);
		this_param = SVAL(cli->inbuf,smb_prcnt);

		if (this_data + *data_len > total_data ||
		    this_param + *param_len > total_param) {
			DEBUG(1,("Data overflow in cli_receive_trans\n"));
			goto out;
		}

		if (this_data + *data_len < this_data ||
				this_data + *data_len < *data_len ||
				this_param + *param_len < this_param ||
				this_param + *param_len < *param_len) {
			DEBUG(1,("Data overflow in cli_receive_trans\n"));
			goto out;
		}

		if (this_data) {
			unsigned int data_offset_out = SVAL(cli->inbuf,smb_drdisp);
			unsigned int data_offset_in = SVAL(cli->inbuf,smb_droff);

			if (data_offset_out > total_data ||
					data_offset_out + this_data > total_data ||
					data_offset_out + this_data < data_offset_out ||
					data_offset_out + this_data < this_data) {
				DEBUG(1,("Data overflow in cli_receive_trans\n"));
				goto out;
			}
			if (data_offset_in > cli->bufsize ||
					data_offset_in + this_data >  cli->bufsize ||
					data_offset_in + this_data < data_offset_in ||
					data_offset_in + this_data < this_data) {
				DEBUG(1,("Data overflow in cli_receive_trans\n"));
				goto out;
			}

			memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data);
		}
		if (this_param) {
			unsigned int param_offset_out = SVAL(cli->inbuf,smb_prdisp);
			unsigned int param_offset_in = SVAL(cli->inbuf,smb_proff);

			if (param_offset_out > total_param ||
					param_offset_out + this_param > total_param ||
					param_offset_out + this_param < param_offset_out ||
					param_offset_out + this_param < this_param) {
				DEBUG(1,("Param overflow in cli_receive_trans\n"));
				goto out;
			}
			if (param_offset_in > cli->bufsize ||
					param_offset_in + this_param >  cli->bufsize ||
					param_offset_in + this_param < param_offset_in ||
					param_offset_in + this_param < this_param) {
				DEBUG(1,("Param overflow in cli_receive_trans\n"));
				goto out;
			}

			memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param);
		}
		*data_len += this_data;
		*param_len += this_param;

		if (total_data <= *data_len && total_param <= *param_len) {
			ret = True;
			break;
		}

		if (!cli_receive_smb(cli)) {
			goto out;
		}

		show_msg(cli->inbuf);

		/* sanity check */
		if (CVAL(cli->inbuf,smb_com) != trans) {
			DEBUG(0,("Expected %s response, got command 0x%02x\n",
				 trans==SMBtrans?"SMBtrans":"SMBtrans2", 
				 CVAL(cli->inbuf,smb_com)));
			goto out;
		}
		if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
			if (NT_STATUS_IS_ERR(cli_nt_error(cli))) {
				goto out;
			}
		}

		/* parse out the total lengths again - they can shrink! */
		if (SVAL(cli->inbuf,smb_tdrcnt) < total_data)
			total_data = SVAL(cli->inbuf,smb_tdrcnt);
		if (SVAL(cli->inbuf,smb_tprcnt) < total_param)
			total_param = SVAL(cli->inbuf,smb_tprcnt);

		if (total_data <= *data_len && total_param <= *param_len) {
			ret = True;
			break;
		}
	}

  out:

	cli_state_seqnum_remove(cli, mid);

	if (ret) {
		/* Ensure the last 2 bytes of param and data are 2 null
		 * bytes. These are malloc'ed, but not included in any
		 * length counts. This allows cli_XX string reading functions
		 * to safely null terminate. */
		if (total_data) {
			SSVAL(*data,total_data,0);
		}
		if (total_param) {
			SSVAL(*param,total_param,0);
		}
	}

	return ret;
}
Example #22
0
BOOL smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16 **string)
{
	UNISTR chaine;
	
	prs_struct *ps=&buffer->prs;
	
	if (MARSHALLING(ps)) {
		uint32 struct_offset = prs_offset(ps);
		uint32 relative_offset;
		uint16 *p;
		uint16 *q;
		uint16 zero=0;
		p=*string;
		q=*string;

		/* first write the last 0 */
		buffer->string_at_end -= 2;
		if(!prs_set_offset(ps, buffer->string_at_end))
			return False;

		if(!prs_uint16("leading zero", ps, depth, &zero))
			return False;

		while (p && (*p!=0)) {	
			while (*q!=0)
				q++;

			/* Yes this should be malloc not talloc. Don't change. */

			chaine.buffer = (uint16 *)
				SMB_MALLOC((q-p+1)*sizeof(uint16));
			if (chaine.buffer == NULL)
				return False;

			memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));

			buffer->string_at_end -= (q-p+1)*sizeof(uint16);

			if(!prs_set_offset(ps, buffer->string_at_end)) {
				SAFE_FREE(chaine.buffer);
				return False;
			}

			/* write the string */
			if (!smb_io_unistr(desc, &chaine, ps, depth)) {
				SAFE_FREE(chaine.buffer);
				return False;
			}
			q++;
			p=q;

			SAFE_FREE(chaine.buffer);
		}
		
		if(!prs_set_offset(ps, struct_offset))
			return False;
		
		relative_offset=buffer->string_at_end - buffer->struct_start;
		/* write its offset */
		if (!prs_uint32("offset", ps, depth, &relative_offset))
			return False;

	} else {

		/* UNMARSHALLING */

		uint32 old_offset;
		uint16 *chaine2=NULL;
		int l_chaine=0;
		int l_chaine2=0;
		size_t realloc_size = 0;

		*string=NULL;
				
		/* read the offset */
		if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
			return False;

		old_offset = prs_offset(ps);
		if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
			return False;
	
		do {
			if (!smb_io_unistr(desc, &chaine, ps, depth))
				return False;
			
			l_chaine=str_len_uni(&chaine);
			
			/* we're going to add two more bytes here in case this
			   is the last string in the array and we need to add 
			   an extra NULL for termination */
			if (l_chaine > 0) {
				realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16);

				/* Yes this should be realloc - it's freed below. JRA */

				if((chaine2=(uint16 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) {
					return False;
				}
				memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
				l_chaine2+=l_chaine+1;
			}
		
		} while(l_chaine!=0);
		
		/* the end should be bould NULL terminated so add 
		   the second one here */
		if (chaine2)
		{
			chaine2[l_chaine2] = '\0';
			*string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size);
			if (!*string) {
				return False;
			}
			SAFE_FREE(chaine2);
		}

		if(!prs_set_offset(ps, old_offset))
			return False;
	}
	return True;
}
Example #23
0
SMB_ACL_T aixacl_to_smbacl(struct acl *file_acl)
{
	struct acl_entry *acl_entry;
	struct ace_id *idp;
	
	struct smb_acl_t *result = SMB_MALLOC_P(struct smb_acl_t);
	struct smb_acl_entry *ace;
	int i;
	
	if (result == NULL) {
		return NULL;
	}
	ZERO_STRUCTP(result);
	
	/* Point to the first acl entry in the acl */
	acl_entry =  file_acl->acl_ext;


	
	DEBUG(10,("acl_entry is %p\n",(void *)acl_entry));
	DEBUG(10,("acl_last(file_acl) id %p\n",(void *)acl_last(file_acl)));

	/* Check if the extended acl bit is on.   *
	 * If it isn't, do not show the           *
	 * contents of the acl since AIX intends *
	 * the extended info to remain unused     */

	if(file_acl->acl_mode & S_IXACL){
		/* while we are not pointing to the very end */
		while(acl_entry < acl_last(file_acl)) {
			/* before we malloc anything, make sure this is  */
			/* a valid acl entry and one that we want to map */
			idp = id_nxt(acl_entry->ace_id);
			if((acl_entry->ace_type == ACC_SPECIFY ||
				(acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
					acl_entry = acl_nxt(acl_entry);
					continue;
			}

			idp = acl_entry->ace_id;
			DEBUG(10,("idp->id_data is %d\n",idp->id_data[0]));
			
			result = SMB_REALLOC(result, sizeof(struct smb_acl_t) +
				     (sizeof(struct smb_acl_entry) *
				      (result->count+1)));
			if (result == NULL) {
				DEBUG(0, ("SMB_REALLOC failed\n"));
				errno = ENOMEM;
				return NULL;
			}
			

			DEBUG(10,("idp->id_type is %d\n",idp->id_type));
			ace = &result->acl[result->count];
			
			ace->a_type = idp->id_type;
							
			switch(ace->a_type) {
			case ACEID_USER: {
			ace->uid = idp->id_data[0];
			DEBUG(10,("case ACEID_USER ace->uid is %d\n",ace->uid));
			ace->a_type = SMB_ACL_USER;
			break;
			}
		
			case ACEID_GROUP: {
			ace->gid = idp->id_data[0];
			DEBUG(10,("case ACEID_GROUP ace->gid is %d\n",ace->gid));
			ace->a_type = SMB_ACL_GROUP;
			break;
			}
			default:
				break;
			}
			/* The access in the acl entries must be left shifted by *
			 * three bites, because they will ultimately be compared *
			 * to S_IRUSR, S_IWUSR, and S_IXUSR.                  */

			switch(acl_entry->ace_type){
			case ACC_PERMIT:
			case ACC_SPECIFY:
				ace->a_perm = acl_entry->ace_access;
				ace->a_perm <<= 6;
				DEBUG(10,("ace->a_perm is %d\n",ace->a_perm));
				break;
			case ACC_DENY:
				/* Since there is no way to return a DENY acl entry *
				 * change to PERMIT and then shift.                 */
				DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
				ace->a_perm = ~acl_entry->ace_access & 7;
				DEBUG(10,("ace->a_perm is %d\n",ace->a_perm));
				ace->a_perm <<= 6;
				break;
			default:
				DEBUG(0, ("unknown ace->type\n"));
			 	SAFE_FREE(result);
				return(0);
			}
		
			result->count++;
			ace->a_perm |= (ace->a_perm & S_IRUSR) ? SMB_ACL_READ : 0;
			ace->a_perm |= (ace->a_perm & S_IWUSR) ? SMB_ACL_WRITE : 0;
			ace->a_perm |= (ace->a_perm & S_IXUSR) ? SMB_ACL_EXECUTE : 0;
			DEBUG(10,("ace->a_perm is %d\n",ace->a_perm));
			
			DEBUG(10,("acl_entry = %p\n",(void *)acl_entry));
			DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
 
			acl_entry = acl_nxt(acl_entry);
		}
	} /* end of if enabled */

	/* Since owner, group, other acl entries are not *
	 * part of the acl entries in an acl, they must  *
	 * be dummied up to become part of the list.     */

	for( i = 1; i < 4; i++) {
		DEBUG(10,("i is %d\n",i));

			result = SMB_REALLOC(result, sizeof(struct smb_acl_t) +
				     (sizeof(struct smb_acl_entry) *
				      (result->count+1)));
			if (result == NULL) {
				DEBUG(0, ("SMB_REALLOC failed\n"));
				errno = ENOMEM;
				DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
				return NULL;
			}
			
		ace = &result->acl[result->count];
		
		ace->uid = 0;
		ace->gid = 0;
		DEBUG(10,("ace->uid = %d\n",ace->uid));
		
		switch(i) {
		case 2:
			ace->a_perm = file_acl->g_access << 6;
			ace->a_type = SMB_ACL_GROUP_OBJ;
			break;

		case 3:
			ace->a_perm = file_acl->o_access << 6;
			ace->a_type = SMB_ACL_OTHER;
			break;
 
		case 1:
			ace->a_perm = file_acl->u_access << 6;
			ace->a_type = SMB_ACL_USER_OBJ;
			break;
 
		default:
			return(NULL);

		}
		ace->a_perm |= ((ace->a_perm & S_IRUSR) ? SMB_ACL_READ : 0);
		ace->a_perm |= ((ace->a_perm & S_IWUSR) ? SMB_ACL_WRITE : 0);
		ace->a_perm |= ((ace->a_perm & S_IXUSR) ? SMB_ACL_EXECUTE : 0);
		
		memcpy(&result->acl[result->count],ace,sizeof(struct smb_acl_entry));
		result->count++;
		DEBUG(10,("ace->a_perm = %d\n",ace->a_perm));
		DEBUG(10,("ace->a_type = %d\n",ace->a_type));
	}


	return result;


}
Example #24
0
static BOOL regdb_store_keys_internal( const char *key, REGSUBKEY_CTR *ctr )
{
	TDB_DATA kbuf, dbuf;
	char *buffer;
	int i = 0;
	uint32 len, buflen;
	BOOL ret = True;
	uint32 num_subkeys = regsubkey_ctr_numkeys( ctr );
	pstring keyname;
	
	if ( !key )
		return False;

	pstrcpy( keyname, key );
	normalize_reg_path( keyname );

	/* allocate some initial memory */
		
	if (!(buffer = (char *)SMB_MALLOC(sizeof(pstring)))) {
		return False;
	}
	buflen = sizeof(pstring);
	len = 0;
	
	/* store the number of subkeys */
	
	len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys );
	
	/* pack all the strings */
	
	for (i=0; i<num_subkeys; i++) {
		len += tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
		if ( len > buflen ) {
			/* allocate some extra space */
			if ((buffer = (char *)SMB_REALLOC( buffer, len*2 )) == NULL) {
				DEBUG(0,("regdb_store_keys: Failed to realloc memory of size [%d]\n", len*2));
				ret = False;
				goto done;
			}
			buflen = len*2;
					
			len = tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
		}		
	}
	
	/* finally write out the data */
	
	kbuf.dptr = keyname;
	kbuf.dsize = strlen(keyname)+1;
	dbuf.dptr = buffer;
	dbuf.dsize = len;
	if ( tdb_store( tdb_reg, kbuf, dbuf, TDB_REPLACE ) == -1) {
		ret = False;
		goto done;
	}

done:		
	SAFE_FREE( buffer );
	
	return ret;
}