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

📄 msdfs.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		ref->ttl = REFERRAL_TTL;		jucn->referral_list = ref;		if (consumedcntp) {			*consumedcntp = strlen(pathname);		}		ret = True;		goto out;	}	pstrcpy(conn_path, lp_pathname(snum));	if (!create_conn_struct(conn, snum, conn_path)) {		return False;	}	/* If not remote & not a self referral, return False */	if (!resolve_dfs_path(ctx, pathname, &dp, conn, False, 			      &jucn->referral_list, &jucn->referral_count,			      self_referralp, consumedcntp)) {		if (!*self_referralp) {			DEBUG(3,("get_referred_path: No valid referrals for path %s\n", pathname));			goto out;		}	}		/* if self_referral, fill up the junction map */	if (*self_referralp) {		if (self_ref(ctx, pathname, jucn, consumedcntp, self_referralp) == False) {			goto out;		}	}		ret = True;out:	conn_free_internal(conn);	return ret;}static int setup_ver2_dfs_referral(char *pathname, char **ppdata, 				   struct junction_map *junction,				   int consumedcnt,				   BOOL self_referral){	char* pdata = *ppdata;	unsigned char uni_requestedpath[1024];	int uni_reqpathoffset1,uni_reqpathoffset2;	int uni_curroffset;	int requestedpathlen=0;	int offset;	int reply_size = 0;	int i=0;	DEBUG(10,("setting up version2 referral\nRequested path:\n"));	requestedpathlen = rpcstr_push(uni_requestedpath, pathname, -1,				       STR_TERMINATE);	if (DEBUGLVL(10)) {	    dump_data(0, (const char *) uni_requestedpath,requestedpathlen);	}	DEBUG(10,("ref count = %u\n",junction->referral_count));	uni_reqpathoffset1 = REFERRAL_HEADER_SIZE + 			VERSION2_REFERRAL_SIZE * junction->referral_count;	uni_reqpathoffset2 = uni_reqpathoffset1 + requestedpathlen;	uni_curroffset = uni_reqpathoffset2 + requestedpathlen;	reply_size = REFERRAL_HEADER_SIZE + VERSION2_REFERRAL_SIZE*junction->referral_count +					2 * requestedpathlen;	DEBUG(10,("reply_size: %u\n",reply_size));	/* add up the unicode lengths of all the referral paths */	for(i=0;i<junction->referral_count;i++) {		DEBUG(10,("referral %u : %s\n",i,junction->referral_list[i].alternate_path));		reply_size += (strlen(junction->referral_list[i].alternate_path)+1)*2;	}	DEBUG(10,("reply_size = %u\n",reply_size));	/* add the unexplained 0x16 bytes */	reply_size += 0x16;	pdata = SMB_REALLOC(pdata,reply_size);	if(pdata == NULL) {		DEBUG(0,("malloc failed for Realloc!\n"));		return -1;	} else {		*ppdata = pdata;	}	/* copy in the dfs requested paths.. required for offset calculations */	memcpy(pdata+uni_reqpathoffset1,uni_requestedpath,requestedpathlen);	memcpy(pdata+uni_reqpathoffset2,uni_requestedpath,requestedpathlen);	/* create the header */	SSVAL(pdata,0,consumedcnt * 2); /* path consumed */	SSVAL(pdata,2,junction->referral_count); /* number of referral in this pkt */	if(self_referral) {		SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER); 	} else {		SIVAL(pdata,4,DFSREF_STORAGE_SERVER);	}	offset = 8;	/* add the referral elements */	for(i=0;i<junction->referral_count;i++) {		struct referral* ref = &junction->referral_list[i];		int unilen;		SSVAL(pdata,offset,2); /* version 2 */		SSVAL(pdata,offset+2,VERSION2_REFERRAL_SIZE);		if(self_referral) {			SSVAL(pdata,offset+4,1);		} else {			SSVAL(pdata,offset+4,0);		}		SSVAL(pdata,offset+6,0); /* ref_flags :use path_consumed bytes? */		SIVAL(pdata,offset+8,ref->proximity);		SIVAL(pdata,offset+12,ref->ttl);		SSVAL(pdata,offset+16,uni_reqpathoffset1-offset);		SSVAL(pdata,offset+18,uni_reqpathoffset2-offset);		/* copy referred path into current offset */		unilen = rpcstr_push(pdata+uni_curroffset, ref->alternate_path,				     -1, STR_UNICODE);		SSVAL(pdata,offset+20,uni_curroffset-offset);		uni_curroffset += unilen;		offset += VERSION2_REFERRAL_SIZE;	}	/* add in the unexplained 22 (0x16) bytes at the end */	memset(pdata+uni_curroffset,'\0',0x16);	return reply_size;}static int setup_ver3_dfs_referral(char *pathname, char **ppdata, 				   struct junction_map *junction,				   int consumedcnt,				   BOOL self_referral){	char* pdata = *ppdata;	unsigned char uni_reqpath[1024];	int uni_reqpathoffset1, uni_reqpathoffset2;	int uni_curroffset;	int reply_size = 0;	int reqpathlen = 0;	int offset,i=0;		DEBUG(10,("setting up version3 referral\n"));	reqpathlen = rpcstr_push(uni_reqpath, pathname, -1, STR_TERMINATE);		if (DEBUGLVL(10)) {	    dump_data(0, (char *) uni_reqpath,reqpathlen);	}	uni_reqpathoffset1 = REFERRAL_HEADER_SIZE + VERSION3_REFERRAL_SIZE * junction->referral_count;	uni_reqpathoffset2 = uni_reqpathoffset1 + reqpathlen;	reply_size = uni_curroffset = uni_reqpathoffset2 + reqpathlen;	for(i=0;i<junction->referral_count;i++) {		DEBUG(10,("referral %u : %s\n",i,junction->referral_list[i].alternate_path));		reply_size += (strlen(junction->referral_list[i].alternate_path)+1)*2;	}	pdata = SMB_REALLOC(pdata,reply_size);	if(pdata == NULL) {		DEBUG(0,("version3 referral setup: malloc failed for Realloc!\n"));		return -1;	} else {		*ppdata = pdata;	}	/* create the header */	SSVAL(pdata,0,consumedcnt * 2); /* path consumed */	SSVAL(pdata,2,junction->referral_count); /* number of referral */	if(self_referral) {		SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER); 	} else {		SIVAL(pdata,4,DFSREF_STORAGE_SERVER);	}		/* copy in the reqpaths */	memcpy(pdata+uni_reqpathoffset1,uni_reqpath,reqpathlen);	memcpy(pdata+uni_reqpathoffset2,uni_reqpath,reqpathlen);		offset = 8;	for(i=0;i<junction->referral_count;i++) {		struct referral* ref = &(junction->referral_list[i]);		int unilen;		SSVAL(pdata,offset,3); /* version 3 */		SSVAL(pdata,offset+2,VERSION3_REFERRAL_SIZE);		if(self_referral) {			SSVAL(pdata,offset+4,1);		} else {			SSVAL(pdata,offset+4,0);		}		SSVAL(pdata,offset+6,0); /* ref_flags :use path_consumed bytes? */		SIVAL(pdata,offset+8,ref->ttl);	    		SSVAL(pdata,offset+12,uni_reqpathoffset1-offset);		SSVAL(pdata,offset+14,uni_reqpathoffset2-offset);		/* copy referred path into current offset */		unilen = rpcstr_push(pdata+uni_curroffset,ref->alternate_path,				     -1, STR_UNICODE | STR_TERMINATE);		SSVAL(pdata,offset+16,uni_curroffset-offset);		/* copy 0x10 bytes of 00's in the ServiceSite GUID */		memset(pdata+offset+18,'\0',16);		uni_curroffset += unilen;		offset += VERSION3_REFERRAL_SIZE;	}	return reply_size;}/****************************************************************** Set up the Dfs referral for the dfs pathname******************************************************************/int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_referral_level, char **ppdata){	struct junction_map junction;	int consumedcnt;	BOOL self_referral = False;	pstring buf;	int reply_size = 0;	char *pathnamep = pathname;	TALLOC_CTX *ctx;	if (!(ctx=talloc_init("setup_dfs_referral"))) {		return -1;	}	ZERO_STRUCT(junction);	/* get the junction entry */	if (!pathnamep) {		talloc_destroy(ctx);		return -1;	}	/* Trim pathname sent by client so it begins with only one backslash.	   Two backslashes confuse some dfs clients	 */	while (pathnamep[0] == '\\' && pathnamep[1] == '\\') {		pathnamep++;	}	pstrcpy(buf, pathnamep);	/* The following call can change cwd. */	if (!get_referred_path(ctx, buf, &junction, &consumedcnt, &self_referral)) {		vfs_ChDir(orig_conn,orig_conn->connectpath);		talloc_destroy(ctx);		return -1;	}	vfs_ChDir(orig_conn,orig_conn->connectpath);		if (!self_referral) {		pathnamep[consumedcnt] = '\0';		if( DEBUGLVL( 3 ) ) {			int i=0;			dbgtext("setup_dfs_referral: Path %s to alternate path(s):",pathnamep);			for(i=0;i<junction.referral_count;i++)				dbgtext(" %s",junction.referral_list[i].alternate_path);			dbgtext(".\n");		}	}	/* create the referral depeding on version */	DEBUG(10,("max_referral_level :%d\n",max_referral_level));	if(max_referral_level<2 || max_referral_level>3) {		max_referral_level = 2;	}	switch(max_referral_level) {	case 2:		reply_size = setup_ver2_dfs_referral(pathnamep, ppdata, &junction, 						     consumedcnt, self_referral);		break;	case 3:		reply_size = setup_ver3_dfs_referral(pathnamep, ppdata, &junction, 						     consumedcnt, self_referral);		break;	default:		DEBUG(0,("setup_dfs_referral: Invalid dfs referral version: %d\n", max_referral_level));		talloc_destroy(ctx);		return -1;	}      	if (DEBUGLVL(10)) {		DEBUGADD(0,("DFS Referral pdata:\n"));		dump_data(0,*ppdata,reply_size);	}	talloc_destroy(ctx);	return reply_size;}/********************************************************************** The following functions are called by the NETDFS RPC pipe functions **********************************************************************//********************************************************************* Creates a junction structure from a Dfs pathname**********************************************************************/BOOL create_junction(char *pathname, struct junction_map *jucn){        struct dfs_path dp;         parse_dfs_path(pathname,&dp);        /* check if path is dfs : validate first token */        if ( !strequal(get_local_machine_name(),dp.hostname) ) {		/* Hostname mismatch, check if one of our IP addresses */		if (!ismyip(*interpret_addr2(dp.hostname))) {			DEBUG(4,("create_junction: Invalid hostname %s in dfs path %s\n",				dp.hostname, pathname));			return False;		}	}	/* Check for a non-DFS share */	if(!lp_msdfs_root(lp_servicenumber(dp.servicename))) {		DEBUG(4,("create_junction: %s is not an msdfs root.\n", dp.servicename));		return False;	}	pstrcpy(jucn->service_name,dp.servicename);	pstrcpy(jucn->volume_name,dp.reqpath);	return True;}/********************************************************************** Forms a valid Unix pathname from the junction  **********************************************************************/static BOOL junction_to_local_path(struct junction_map *jucn, char *path,				   int max_pathlen, connection_struct *conn){	int snum;	pstring conn_path;	if(!path || !jucn) {		return False;	}	snum = lp_servicenumber(jucn->service_name);	if(snum < 0) {		return False;	}	safe_strcpy(path, lp_pathname(snum), max_pathlen-1);	safe_strcat(path, "/", max_pathlen-1);	safe_strcat(path, jucn->volume_name, max_pathlen-1);	pstrcpy(conn_path, lp_pathname(snum));	if (!create_conn_struct(conn, snum, conn_path)) {		return False;	}	return True;}BOOL create_msdfs_link(struct junction_map *jucn, BOOL exists){	pstring path;	pstring msdfs_link;	connection_struct conns; 	connection_struct *conn = &conns;	int i=0;	BOOL insert_comma = False;	BOOL ret = False;	ZERO_STRUCT(conns);	if(!junction_to_local_path(jucn, path, sizeof(path), conn)) {		return False;	}  	/* form the msdfs_link contents */	pstrcpy(msdfs_link, "msdfs:");	for(i=0; i<jucn->referral_count; i++) {		char* refpath = jucn->referral_list[i].alternate_path;      		trim_char(refpath, '\\', '\\');		if(*refpath == '\0') {			if (i == 0) {				insert_comma = False;			}			continue;		}		if (i > 0 && insert_comma) {			pstrcat(msdfs_link, ",");		}		pstrcat(msdfs_link, refpath);		if (!insert_comma) {			insert_comma = True;		}	}	DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n", path, msdfs_link));	if(exists) {		if(SMB_VFS_UNLINK(conn,path)!=0) {			goto out;		}	}	if(SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) {		DEBUG(1,("create_msdfs_link: symlink failed %s -> %s\nError: %s\n", 				path, msdfs_link, strerror(errno)));		goto out;	}			ret = True;	out:	conn_free_internal(conn);	return ret;}BOOL remove_msdfs_link(struct junction_map *jucn){	pstring path;	connection_struct conns; 	connection_struct *conn = &conns;	BOOL ret = False;	ZERO_STRUCT(conns);	if( junction_to_local_path(jucn, path, sizeof(path), conn) ) {		if( SMB_VFS_UNLINK(conn, path) == 0 ) {			ret = True;		}		talloc_destroy( conn->mem_ctx );	}	conn_free_internal(conn);	return ret;}static int form_junctions(TALLOC_CTX *ctx, int snum, struct junction_map *jucn, int jn_remain){	int cnt = 0;	SMB_STRUCT_DIR *dirp;	char* dname;	pstring connect_path;	char* service_name = lp_servicename(snum);	connection_struct conn;	struct referral *ref = NULL; 	ZERO_STRUCT(conn);	if (jn_remain <= 0) {		return 0;	}	pstrcpy(connect_path,lp_pathname(snum));	if(*connect_path == '\0') {		return 0;	}	/*	 * Fake up a connection struct for the VFS layer.	 */	if (!create_conn_struct(&conn, snum, connect_path)) {		return 0;	}	/* form a junction for the msdfs root - convention 	   DO NOT REMOVE THIS: NT clients will not work with us	   if this is not present	*/ 	pstrcpy(jucn[cnt].service_name, service_name);	jucn[cnt].volume_name[0] = '\0';	jucn[cnt].referral_count = 1;	ref = jucn[cnt].referral_list = TALLOC_P(ctx, struct referral);	if (jucn[cnt].referral_list == NULL) {		DEBUG(0, ("Malloc failed!\n"));		goto out;	}	ref->proximity = 0;	ref->ttl = REFERRAL_TTL;	if (*lp_msdfs_proxy(snum) != '\0') {		pstrcpy(ref->alternate_path, lp_msdfs_proxy(snum));		goto out;	}			slprintf(ref->alternate_path, sizeof(pstring)-1,		 "\\\\%s\\%s", get_local_machine_name(), service_name);	cnt++;	/* Now enumerate all dfs links */	dirp = SMB_VFS_OPENDIR(&conn, ".", NULL, 0);	if(!dirp) {		goto out;	}	while ((dname = vfs_readdirname(&conn, dirp)) != NULL) {		if (cnt >= jn_remain) {			SMB_VFS_CLOSEDIR(&conn,dirp);			DEBUG(2, ("ran out of MSDFS junction slots"));			goto out;		}		if (is_msdfs_link(ctx, &conn, dname, &jucn[cnt].referral_list,				  &jucn[cnt].referral_count, NULL)) {			pstrcpy(jucn[cnt].service_name, service_name);			pstrcpy(jucn[cnt].volume_name, dname);			cnt++;		}	}		SMB_VFS_CLOSEDIR(&conn,dirp);out:	conn_free_internal(&conn);	return cnt;}int enum_msdfs_links(TALLOC_CTX *ctx, struct junction_map *jucn, int jn_max){	int i=0;	int jn_count = 0;	if(!lp_host_msdfs()) {		return 0;	}	for(i=0;i < lp_numservices() && (jn_max - jn_count) > 0;i++) {		if(lp_msdfs_root(i)) {			jn_count += form_junctions(ctx, i,jucn,jn_max - jn_count);		}	}	return jn_count;}

⌨️ 快捷键说明

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