コード例 #1
0
ファイル: clilist.c プロジェクト: AllardJ/Tomato
static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo,
					uint32 *p_resume_key, DATA_BLOB *p_last_name_raw, uint32 *p_last_name_raw_len)
{
	file_info finfo2;
	int len;
	char *base = p;

	if (!finfo) {
		finfo = &finfo2;
	}

	if (p_resume_key) {
		*p_resume_key = 0;
	}
	memcpy(finfo,&def_finfo,sizeof(*finfo));
	finfo->cli = cli;

	switch (level) {
		case 1: /* OS/2 understands this */
			/* these dates are converted to GMT by
                           make_unix_date */
			finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4));
			finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8));
			finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12));
			finfo->size = IVAL(p,16);
			finfo->mode = CVAL(p,24);
			len = CVAL(p, 26);
			p += 27;
			p += clistr_align_in(cli, p, 0);
			/* the len+2 below looks strange but it is
			   important to cope with the differences
			   between win2000 and win9x for this call
			   (tridge) */
			p += clistr_pull(cli, finfo->name, p,
					 sizeof(finfo->name),
					 len+2, 
					 STR_TERMINATE);
			return PTR_DIFF(p, base);

		case 2: /* this is what OS/2 uses mostly */
			/* these dates are converted to GMT by
                           make_unix_date */
			finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4));
			finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8));
			finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12));
			finfo->size = IVAL(p,16);
			finfo->mode = CVAL(p,24);
			len = CVAL(p, 30);
			p += 31;
			/* check for unisys! */
			p += clistr_pull(cli, finfo->name, p,
					 sizeof(finfo->name),
					 len, 
					 STR_NOALIGN);
			return PTR_DIFF(p, base) + 1;
			
		case 260: /* NT uses this, but also accepts 2 */
		{
			size_t namelen, slen;
			p += 4; /* next entry offset */

			if (p_resume_key) {
				*p_resume_key = IVAL(p,0);
			}
			p += 4; /* fileindex */
				
			/* Offset zero is "create time", not "change time". */
			p += 8;
			finfo->atime_ts = interpret_long_date(p);
			p += 8;
			finfo->mtime_ts = interpret_long_date(p);
			p += 8;
			finfo->ctime_ts = interpret_long_date(p);
			p += 8;
			finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0);
			p += 8;
			p += 8; /* alloc size */
			finfo->mode = CVAL(p,0);
			p += 4;
			namelen = IVAL(p,0);
			p += 4;
			p += 4; /* EA size */
			slen = SVAL(p, 0);
			p += 2; 
			{
				/* stupid NT bugs. grr */
				int flags = 0;
				if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE;
				clistr_pull(cli, finfo->short_name, p,
					    sizeof(finfo->short_name),
					    slen, flags);
			}
			p += 24; /* short name? */	  
			clistr_pull(cli, finfo->name, p,
				    sizeof(finfo->name),
				    namelen, 0);

			/* To be robust in the face of unicode conversion failures
			   we need to copy the raw bytes of the last name seen here.
			   Namelen doesn't include the terminating unicode null, so
			   copy it here. */

			if (p_last_name_raw && p_last_name_raw_len) {
				if (namelen + 2 > p_last_name_raw->length) {
					memset(p_last_name_raw->data, '\0', sizeof(p_last_name_raw->length));
					*p_last_name_raw_len = 0;
				} else {
					memcpy(p_last_name_raw->data, p, namelen);
					SSVAL(p_last_name_raw->data, namelen, 0);
					*p_last_name_raw_len = namelen + 2;
				}
			}
			return (size_t)IVAL(base, 0);
		}
	}
	
	DEBUG(1,("Unknown long filename format %d\n",level));
	return (size_t)IVAL(base,0);
}
コード例 #2
0
ファイル: clirap.c プロジェクト: aosm/samba
BOOL cli_qfileinfo(struct cli_state *cli, int fnum, 
		   uint16 *mode, SMB_OFF_T *size,
		   struct timespec *create_time,
                   struct timespec *access_time,
                   struct timespec *write_time, 
		   struct timespec *change_time,
                   SMB_INO_T *ino)
{
	unsigned int data_len = 0;
	unsigned int param_len = 0;
	uint16 setup = TRANSACT2_QFILEINFO;
	pstring param;
	char *rparam=NULL, *rdata=NULL;

	/* if its a win95 server then fail this - win95 totally screws it
	   up */
	if (cli->win95) return False;

	param_len = 4;

	memset(param, 0, param_len);
	SSVAL(param, 0, fnum);
	SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO);

	if (!cli_send_trans(cli, SMBtrans2, 
                            NULL,                         /* name */
                            -1, 0,                        /* fid, flags */
                            &setup, 1, 0,                 /* setup, length, max */
                            param, param_len, 2,          /* param, length, max */
                            NULL, data_len, cli->max_xmit /* data, length, max */
                           )) {
		return False;
	}

	if (!cli_receive_trans(cli, SMBtrans2,
                               &rparam, &param_len,
                               &rdata, &data_len)) {
		return False;
	}

	if (!rdata || data_len < 68) {
		return False;
	}

	if (create_time) {
		*create_time = interpret_long_date(rdata+0);
	}
	if (access_time) {
		*access_time = interpret_long_date(rdata+8);
	}
	if (write_time) {
		*write_time = interpret_long_date(rdata+16);
	}
	if (change_time) {
		*change_time = interpret_long_date(rdata+24);
	}
	if (mode) {
		*mode = SVAL(rdata, 32);
	}
	if (size) {
                *size = IVAL2_TO_SMB_BIG_UINT(rdata,48);
	}
	if (ino) {
		*ino = IVAL(rdata, 64);
	}

	SAFE_FREE(rdata);
	SAFE_FREE(rparam);
	return True;
}
コード例 #3
0
static size_t interpret_long_filename(TALLOC_CTX *ctx,
					struct cli_state *cli,
					int level,
					const char *base_ptr,
					uint16_t recv_flags2,
					const char *p,
					const char *pdata_end,
					struct file_info *finfo,
					uint32 *p_resume_key,
					DATA_BLOB *p_last_name_raw)
{
	int len;
	size_t ret;
	const char *base = p;

	data_blob_free(p_last_name_raw);

	if (p_resume_key) {
		*p_resume_key = 0;
	}
	ZERO_STRUCTP(finfo);

	switch (level) {
		case SMB_FIND_INFO_STANDARD: /* OS/2 understands this */
			/* these dates are converted to GMT by
                           make_unix_date */
			if (pdata_end - base < 27) {
				return pdata_end - base;
			}
			finfo->ctime_ts = convert_time_t_to_timespec(
				make_unix_date2(p+4, smb1cli_conn_server_time_zone(cli->conn)));
			finfo->atime_ts = convert_time_t_to_timespec(
				make_unix_date2(p+8, smb1cli_conn_server_time_zone(cli->conn)));
			finfo->mtime_ts = convert_time_t_to_timespec(
				make_unix_date2(p+12, smb1cli_conn_server_time_zone(cli->conn)));
			finfo->size = IVAL(p,16);
			finfo->mode = CVAL(p,24);
			len = CVAL(p, 26);
			p += 27;
			if (recv_flags2 & FLAGS2_UNICODE_STRINGS) {
				p += ucs2_align(base_ptr, p, STR_UNICODE);
			}

			/* We can safely use len here (which is required by OS/2)
			 * and the NAS-BASIC server instead of +2 or +1 as the
			 * STR_TERMINATE flag below is
			 * actually used as the length calculation.
			 * The len is merely an upper bound.
			 * Due to the explicit 2 byte null termination
			 * in cli_receive_trans/cli_receive_nt_trans
			 * we know this is safe. JRA + kukks
			 */

			if (p + len > pdata_end) {
				return pdata_end - base;
			}

			/* the len+2 below looks strange but it is
			   important to cope with the differences
			   between win2000 and win9x for this call
			   (tridge) */
			ret = clistr_pull_talloc(ctx,
						base_ptr,
						recv_flags2,
						&finfo->name,
						p,
						len+2,
						STR_TERMINATE);
			if (ret == (size_t)-1) {
				return pdata_end - base;
			}
			p += ret;
			return PTR_DIFF(p, base);

		case SMB_FIND_EA_SIZE: /* this is what OS/2 uses mostly */
			/* these dates are converted to GMT by
                           make_unix_date */
			if (pdata_end - base < 31) {
				return pdata_end - base;
			}
			finfo->ctime_ts = convert_time_t_to_timespec(
				make_unix_date2(p+4, smb1cli_conn_server_time_zone(cli->conn)));
			finfo->atime_ts = convert_time_t_to_timespec(
				make_unix_date2(p+8, smb1cli_conn_server_time_zone(cli->conn)));
			finfo->mtime_ts = convert_time_t_to_timespec(
				make_unix_date2(p+12, smb1cli_conn_server_time_zone(cli->conn)));
			finfo->size = IVAL(p,16);
			finfo->mode = CVAL(p,24);
			len = CVAL(p, 30);
			p += 31;
			/* check for unisys! */
			if (p + len + 1 > pdata_end) {
				return pdata_end - base;
			}
			ret = clistr_pull_talloc(ctx,
						base_ptr,
						recv_flags2,
						&finfo->name,
						p,
					 	len,
						STR_NOALIGN);
			if (ret == (size_t)-1) {
				return pdata_end - base;
			}
			p += ret;
			return PTR_DIFF(p, base) + 1;

		case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: /* NT uses this, but also accepts 2 */
		{
			size_t namelen, slen;

			if (pdata_end - base < 94) {
				return pdata_end - base;
			}

			p += 4; /* next entry offset */

			if (p_resume_key) {
				*p_resume_key = IVAL(p,0);
			}
			p += 4; /* fileindex */

			/* Offset zero is "create time", not "change time". */
			p += 8;
			finfo->atime_ts = interpret_long_date(p);
			p += 8;
			finfo->mtime_ts = interpret_long_date(p);
			p += 8;
			finfo->ctime_ts = interpret_long_date(p);
			p += 8;
			finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0);
			p += 8;
			p += 8; /* alloc size */
			finfo->mode = CVAL(p,0);
			p += 4;
			namelen = IVAL(p,0);
			p += 4;
			p += 4; /* EA size */
			slen = SVAL(p, 0);
			if (slen > 24) {
				/* Bad short name length. */
				return pdata_end - base;
			}
			p += 2;
			ret = clistr_pull_talloc(ctx,
						base_ptr,
						recv_flags2,
						&finfo->short_name,
						p,
						slen,
						STR_UNICODE);
			if (ret == (size_t)-1) {
				return pdata_end - base;
			}
			p += 24; /* short name? */
			if (p + namelen < p || p + namelen > pdata_end) {
				return pdata_end - base;
			}
			ret = clistr_pull_talloc(ctx,
						base_ptr,
						recv_flags2,
						&finfo->name,
						p,
				    		namelen,
						0);
			if (ret == (size_t)-1) {
				return pdata_end - base;
			}

			/* To be robust in the face of unicode conversion failures
			   we need to copy the raw bytes of the last name seen here.
			   Namelen doesn't include the terminating unicode null, so
			   copy it here. */

			if (p_last_name_raw) {
				*p_last_name_raw = data_blob(NULL, namelen+2);
				memcpy(p_last_name_raw->data, p, namelen);
				SSVAL(p_last_name_raw->data, namelen, 0);
			}
			return calc_next_entry_offset(base, pdata_end);
		}
	}

	DEBUG(1,("Unknown long filename format %d\n",level));
	return calc_next_entry_offset(base, pdata_end);
}
コード例 #4
0
ファイル: clirap.c プロジェクト: aosm/samba
BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, 
		    struct timespec *create_time,
                    struct timespec *access_time,
                    struct timespec *write_time, 
		    struct timespec *change_time,
                    SMB_OFF_T *size, uint16 *mode,
		    SMB_INO_T *ino)
{
	unsigned int data_len = 0;
	unsigned int param_len = 0;
	uint16 setup = TRANSACT2_QPATHINFO;
	pstring param;
	char *rparam=NULL, *rdata=NULL;
	char *p;

	p = param;
	memset(p, 0, 6);
	SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO);
	p += 6;
	p += clistr_push(cli, p, fname, sizeof(pstring)-6, 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, data_len, cli->max_xmit /* data, length, max */
                           )) {
		return False;
	}

	if (!cli_receive_trans(cli, SMBtrans2,
                               &rparam, &param_len,
                               &rdata, &data_len)) {
		return False;
	}

	if (!rdata || data_len < 22) {
		return False;
	}
        
	if (create_time) {
                *create_time = interpret_long_date(rdata+0);
	}
	if (access_time) {
		*access_time = interpret_long_date(rdata+8);
	}
	if (write_time) {
		*write_time = interpret_long_date(rdata+16);
	}
	if (change_time) {
		*change_time = interpret_long_date(rdata+24);
	}
	if (mode) {
		*mode = SVAL(rdata, 32);
	}
	if (size) {
                *size = IVAL2_TO_SMB_BIG_UINT(rdata,48);
	}
	if (ino) {
		*ino = IVAL(rdata, 64);
	}

	SAFE_FREE(rdata);
	SAFE_FREE(rparam);
	return True;
}
コード例 #5
0
ファイル: clifile.c プロジェクト: jameshilliard/WECB-BH-GPL
BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf)
{
	unsigned int param_len = 0;
	unsigned int data_len = 0;
	uint16 setup = TRANSACT2_QPATHINFO;
	char param[sizeof(pstring)+6];
	char *rparam=NULL, *rdata=NULL;
	char *p;

	ZERO_STRUCTP(sbuf);

	p = param;
	memset(p, 0, 6);
	SSVAL(p, 0, SMB_QUERY_FILE_UNIX_BASIC);
	p += 6;
	p += clistr_push(cli, p, name, sizeof(pstring)-6, 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, 2,         /* param, length, max */
		NULL,  0, cli->max_xmit      /* data, length, max */
		)) {
			return False;
	}

	if (!cli_receive_trans(cli, SMBtrans2,
		&rparam, &param_len,
		&rdata, &data_len)) {
			return False;
	}

	if (data_len < 96) {
		SAFE_FREE(rdata);
		SAFE_FREE(rparam);
		return False;
	}

	sbuf->st_size = IVAL2_TO_SMB_BIG_UINT(rdata,0);     /* total size, in bytes */
	sbuf->st_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8);   /* number of blocks allocated */
#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
	sbuf->st_blocks /= STAT_ST_BLOCKSIZE;
#else
	/* assume 512 byte blocks */
	sbuf->st_blocks /= 512;
#endif
	sbuf->st_ctime = interpret_long_date(rdata + 16);    /* time of last change */
	sbuf->st_atime = interpret_long_date(rdata + 24);    /* time of last access */
	sbuf->st_mtime = interpret_long_date(rdata + 32);    /* time of last modification */
	sbuf->st_uid = (uid_t) IVAL(rdata,40);      /* user ID of owner */
	sbuf->st_gid = (gid_t) IVAL(rdata,48);      /* group ID of owner */
	sbuf->st_mode |= unix_filetype_from_wire(IVAL(rdata, 56));
#if defined(HAVE_MAKEDEV)
	{
		uint32 dev_major = IVAL(rdata,60);
		uint32 dev_minor = IVAL(rdata,68);
		sbuf->st_rdev = makedev(dev_major, dev_minor);
	}
#endif
	sbuf->st_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(rdata,76);      /* inode */
	sbuf->st_mode |= wire_perms_to_unix(IVAL(rdata,84));     /* protection */
	sbuf->st_nlink = IVAL(rdata,92);    /* number of hard links */

	SAFE_FREE(rdata);
	SAFE_FREE(rparam);

	return True;
}