Esempio n. 1
0
static bool delete_sid_cache(const struct dom_sid* psid)
{
	DATA_BLOB sid = data_blob_const(psid, ndr_size_dom_sid(psid, 0));
	DATA_BLOB id;
	if (memcache_lookup(NULL, SID_GID_CACHE, sid, &id)) {
		DEBUG(3, ("Delete mapping %s <-> GID %d from memcache\n",
			  sid_string_dbg(psid), *(int*)id.data));
		memcache_delete(NULL, SID_GID_CACHE, sid);
		memcache_delete(NULL, GID_SID_CACHE, id);
	} else if (memcache_lookup(NULL, SID_UID_CACHE, sid, &id)) {
		DEBUG(3, ("Delete mapping %s <-> UID %d from memcache\n",
			  sid_string_dbg(psid), *(int*)id.data));
		memcache_delete(NULL, SID_UID_CACHE, sid);
		memcache_delete(NULL, UID_SID_CACHE, id);
	} else {
		DEBUG(3, ("SID %s is not memcached!\n", sid_string_dbg(psid)));
		return false;
	}
	return true;
}
Esempio n. 2
0
static bool delete_gid_cache(gid_t pgid)
{
	DATA_BLOB gid = data_blob_const(&pgid, sizeof(pgid));
	DATA_BLOB sid;
	if (!memcache_lookup(NULL, GID_SID_CACHE, gid, &sid)) {
		DEBUG(3, ("GID %d is not memcached!\n", (int)pgid));
		return false;
	}
	DEBUG(3, ("Delete mapping GID %d <-> %s from memcache\n", (int)pgid,
		  sid_string_dbg((struct dom_sid*)sid.data)));
	memcache_delete(NULL, SID_GID_CACHE, sid);
	memcache_delete(NULL, GID_SID_CACHE, gid);
	return true;
}
Esempio n. 3
0
/*
  lookup an entry in the prefix cache. Return NULL if not found.
*/
static char *cache_lookup(TALLOC_CTX *mem_ctx, unsigned int hash)
{
	DATA_BLOB value;

	if (!memcache_lookup(smbd_memcache(), MANGLE_HASH2_CACHE,
			     data_blob_const(&hash, sizeof(hash)), &value)) {
		return NULL;
	}

	SMB_ASSERT((value.length > 0)
		   && (value.data[value.length-1] == '\0'));

	return talloc_strdup(mem_ctx, (char *)value.data);
}
Esempio n. 4
0
/* string_match - match string s against token tok */
static bool string_match(const char *tok,const char *s)
{
	size_t     tok_len;
	size_t     str_len;
	const char   *cut;

	/* Return true if a token has the magic value "ALL". Return
	 * true if the token is "FAIL". If the token starts with a "."
	 * (domain name), return true if it matches the last fields of
	 * the string. If the token has the magic value "LOCAL",
	 * return true if the string does not contain a "."
	 * character. If the token ends on a "." (network number),
	 * return true if it matches the first fields of the
	 * string. If the token begins with a "@" (netgroup name),
	 * return true if the string is a (host) member of the
	 * netgroup. Return true if the token fully matches the
	 * string. If the token is a netnumber/netmask pair, return
	 * true if the address is a member of the specified subnet.
	 */

	if (tok[0] == '.') {			/* domain: match last fields */
		if ((str_len = strlen(s)) > (tok_len = strlen(tok))
		    && strequal(tok, s + str_len - tok_len)) {
			return true;
		}
	} else if (tok[0] == '@') { /* netgroup: look it up */
#ifdef	HAVE_NETGROUP
		DATA_BLOB tmp;
		char *mydomain = NULL;
		char *hostname = NULL;
		bool netgroup_ok = false;

		if (memcache_lookup(
			    NULL, SINGLETON_CACHE,
			    data_blob_string_const_null("yp_default_domain"),
			    &tmp)) {

			SMB_ASSERT(tmp.length > 0);
			mydomain = (tmp.data[0] == '\0')
				? NULL : (char *)tmp.data;
		}
		else {
			yp_get_default_domain(&mydomain);

			memcache_add(
				NULL, SINGLETON_CACHE,
				data_blob_string_const_null("yp_default_domain"),
				data_blob_string_const_null(mydomain?mydomain:""));
		}

		if (!mydomain) {
			DEBUG(0,("Unable to get default yp domain. "
				"Try without it.\n"));
		}
		if (!(hostname = SMB_STRDUP(s))) {
			DEBUG(1,("out of memory for strdup!\n"));
			return false;
		}

		netgroup_ok = innetgr(tok + 1, hostname, (char *) 0, mydomain);

		DEBUG(5,("looking for %s of domain %s in netgroup %s gave %s\n",
			 hostname,
			 mydomain?mydomain:"(ANY)",
			 tok+1,
			 BOOLSTR(netgroup_ok)));

		SAFE_FREE(hostname);

		if (netgroup_ok)
			return true;
#else
		DEBUG(0,("access: netgroup support is not configured\n"));
		return false;
#endif
	} else if (strequal(tok, "ALL")) {	/* all: match any */
		return true;
	} else if (strequal(tok, "FAIL")) {	/* fail: match any */
		return true;
	} else if (strequal(tok, "LOCAL")) {	/* local: no dots */
		if (strchr_m(s, '.') == 0 && !strequal(s, "unknown")) {
			return true;
		}
	} else if (strequal(tok, s)) {   /* match host name or address */
		return true;
	} else if (tok[(tok_len = strlen(tok)) - 1] == '.') {	/* network */
		if (strncmp(tok, s, tok_len) == 0) {
			return true;
		}
	} else if ((cut = strchr_m(tok, '/')) != 0) {	/* netnumber/netmask */
		if ((isdigit(s[0]) && strchr_m(tok, '.') != NULL) ||
			(tok[0] == '[' && cut > tok && cut[-1] == ']') ||
			((isxdigit(s[0]) || s[0] == ':') &&
				strchr_m(tok, ':') != NULL)) {
			/* IPv4/netmask or
			 * [IPv6:addr]/netmask or IPv6:addr/netmask */
			return masked_match(tok, cut, s);
		}
	} else if (strchr_m(tok, '*') != 0 || strchr_m(tok, '?')) {
		return unix_wild_match(tok, s);
	}
	return false;
}
Esempio n. 5
0
bool stat_cache_lookup(connection_struct *conn,
			bool posix_paths,
			char **pp_name,
			char **pp_dirpath,
			char **pp_start,
			SMB_STRUCT_STAT *pst)
{
	char *chk_name;
	size_t namelen;
	bool sizechanged = False;
	unsigned int num_components = 0;
	char *translated_path;
	size_t translated_path_length;
	DATA_BLOB data_val;
	char *name;
	TALLOC_CTX *ctx = talloc_tos();
	struct smb_filename smb_fname;
	int ret;

	*pp_dirpath = NULL;
	*pp_start = *pp_name;

	if (!lp_stat_cache()) {
		return False;
	}

	name = *pp_name;
	namelen = strlen(name);

	DO_PROFILE_INC(statcache_lookups);

	/*
	 * Don't lookup trivial valid directory entries.
	 */
	if ((*name == '\0') || ISDOT(name) || ISDOTDOT(name)) {
		return False;
	}

	if (conn->case_sensitive) {
		chk_name = talloc_strdup(ctx,name);
		if (!chk_name) {
			DEBUG(0, ("stat_cache_lookup: strdup failed!\n"));
			return False;
		}

	} else {
		chk_name = talloc_strdup_upper(ctx,name);
		if (!chk_name) {
			DEBUG(0, ("stat_cache_lookup: talloc_strdup_upper failed!\n"));
			return False;
		}

		/*
		 * In some language encodings the length changes
		 * if we uppercase. We need to treat this differently
		 * below.
		 */
		if (strlen(chk_name) != namelen) {
			sizechanged = True;
		}
	}

	while (1) {
		char *sp;

		data_val = data_blob_null;

		if (memcache_lookup(
			    smbd_memcache(), STAT_CACHE,
			    data_blob_const(chk_name, strlen(chk_name)),
			    &data_val)) {
			break;
		}

		DEBUG(10,("stat_cache_lookup: lookup failed for name [%s]\n",
				chk_name ));
		/*
		 * Didn't find it - remove last component for next try.
		 */
		if (!(sp = strrchr_m(chk_name, '/'))) {
			/*
			 * We reached the end of the name - no match.
			 */
			DO_PROFILE_INC(statcache_misses);
			TALLOC_FREE(chk_name);
			return False;
		}

		*sp = '\0';

		/*
		 * Count the number of times we have done this, we'll
		 * need it when reconstructing the string.
		 */

		if (sizechanged) {
			num_components++;
		}

		if ((*chk_name == '\0')
		    || ISDOT(chk_name) || ISDOTDOT(chk_name)) {
			DO_PROFILE_INC(statcache_misses);
			TALLOC_FREE(chk_name);
			return False;
		}
	}

	translated_path = talloc_strdup(ctx,(char *)data_val.data);
	if (!translated_path) {
		smb_panic("talloc failed");
	}
	translated_path_length = data_val.length - 1;

	DEBUG(10,("stat_cache_lookup: lookup succeeded for name [%s] "
		  "-> [%s]\n", chk_name, translated_path ));
	DO_PROFILE_INC(statcache_hits);

	ZERO_STRUCT(smb_fname);
	smb_fname.base_name = translated_path;

	if (posix_paths) {
		ret = SMB_VFS_LSTAT(conn, &smb_fname);
	} else {
		ret = SMB_VFS_STAT(conn, &smb_fname);
	}

	if (ret != 0) {
		/* Discard this entry - it doesn't exist in the filesystem. */
		memcache_delete(smbd_memcache(), STAT_CACHE,
				data_blob_const(chk_name, strlen(chk_name)));
		TALLOC_FREE(chk_name);
		TALLOC_FREE(translated_path);
		return False;
	}
	*pst = smb_fname.st;

	if (!sizechanged) {
		memcpy(*pp_name, translated_path,
		       MIN(namelen, translated_path_length));
	} else {
		if (num_components == 0) {
			name = talloc_strndup(ctx, translated_path,
					   translated_path_length);
		} else {
			char *sp;

			sp = strnrchr_m(name, '/', num_components);
			if (sp) {
				name = talloc_asprintf(ctx,"%.*s%s",
					 (int)translated_path_length,
					 translated_path, sp);
			} else {
				name = talloc_strndup(ctx,
						translated_path,
						translated_path_length);
			}
		}
		if (name == NULL) {
			/*
			 * TODO: Get us out of here with a real error message
			 */
			smb_panic("talloc failed");
		}
		TALLOC_FREE(*pp_name);
		*pp_name = name;
	}


	/* set pointer for 'where to start' on fixing the rest of the name */
	*pp_start = &name[translated_path_length];
	if (**pp_start == '/') {
		++*pp_start;
	}

	*pp_dirpath = translated_path;
	TALLOC_FREE(chk_name);
	return (namelen == translated_path_length);
}