Ejemplo n.º 1
0
bool is_share_read_only_for_token(const char *username,
				  const char *domain,
				  const struct nt_user_token *token,
				  connection_struct *conn)
{
	int snum = SNUM(conn);
	bool result = conn->read_only;

	if (lp_readlist(snum) != NULL) {
		if (token_contains_name_in_list(username, domain,
						lp_servicename(snum), token,
						lp_readlist(snum))) {
			result = True;
		}
	}

	if (lp_writelist(snum) != NULL) {
		if (token_contains_name_in_list(username, domain,
						lp_servicename(snum), token,
						lp_writelist(snum))) {
			result = False;
		}
	}

	DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user "
		  "%s\n", lp_servicename(snum),
		  result ? "read-only" : "read-write", username));

	return result;
}
Ejemplo n.º 2
0
bool user_ok_token(const char *username, const char *domain,
		   const struct nt_user_token *token, int snum)
{
	if (lp_invalid_users(snum) != NULL) {
		if (token_contains_name_in_list(username, domain,
						lp_servicename(snum),
						token,
						lp_invalid_users(snum))) {
			DEBUG(10, ("User %s in 'invalid users'\n", username));
			return False;
		}
	}

	if (lp_valid_users(snum) != NULL) {
		if (!token_contains_name_in_list(username, domain,
						 lp_servicename(snum), token,
						 lp_valid_users(snum))) {
			DEBUG(10, ("User %s not in 'valid users'\n",
				   username));
			return False;
		}
	}

	if (lp_onlyuser(snum)) {
		const char *list[2];
		list[0] = lp_username(snum);
		list[1] = NULL;
		if ((list[0] == NULL) || (*list[0] == '\0')) {
			DEBUG(0, ("'only user = yes' and no 'username ='******'username'\n", username));
			return False;
		}
	}

	DEBUG(10, ("user_ok_token: share %s is ok for unix user %s\n",
		   lp_servicename(snum), username));

	return True;
}
Ejemplo n.º 3
0
static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
{
	unsigned int i;
	struct vuid_cache_entry *ent = NULL;
	BOOL readonly_share;

	for (i=0;i<conn->vuid_cache.entries && i< VUID_CACHE_SIZE;i++) {
		if (conn->vuid_cache.array[i].vuid == vuser->vuid) {
			ent = &conn->vuid_cache.array[i];
			conn->read_only = ent->read_only;
			conn->admin_user = ent->admin_user;
			return(True);
		}
	}

	if (!user_ok_token(vuser->user.unix_name, vuser->nt_user_token, snum))
		return(False);

	readonly_share = is_share_read_only_for_token(vuser->user.unix_name,
						      vuser->nt_user_token,
						      conn->service);

	if (!readonly_share &&
	    !share_access_check(conn, snum, vuser, FILE_WRITE_DATA)) {
		/* smb.conf allows r/w, but the security descriptor denies
		 * write. Fall back to looking at readonly. */
		readonly_share = True;
		DEBUG(5,("falling back to read-only access-evaluation due to "
			 "security descriptor\n"));
	}

	if (!share_access_check(conn, snum, vuser,
				readonly_share ?
				FILE_READ_DATA : FILE_WRITE_DATA)) {
		return False;
	}

	i = conn->vuid_cache.entries % VUID_CACHE_SIZE;
	if (conn->vuid_cache.entries < VUID_CACHE_SIZE)
		conn->vuid_cache.entries++;

	ent = &conn->vuid_cache.array[i];
	ent->vuid = vuser->vuid;
	ent->read_only = readonly_share;

	ent->admin_user = token_contains_name_in_list(
		vuser->user.unix_name, NULL, vuser->nt_user_token,
		lp_admin_users(conn->service));

	conn->read_only = ent->read_only;
	conn->admin_user = ent->admin_user;

	return(True);
}
Ejemplo n.º 4
0
Archivo: uid.c Proyecto: Arkhont/samba
static bool check_user_ok(connection_struct *conn,
			uint16_t vuid,
			const struct auth_serversupplied_info *session_info,
			int snum)
{
	bool valid_vuid = (vuid != UID_FIELD_INVALID);
	unsigned int i;
	bool readonly_share;
	bool admin_user;

	if (valid_vuid) {
		struct vuid_cache_entry *ent;

		for (i=0; i<VUID_CACHE_SIZE; i++) {
			ent = &conn->vuid_cache.array[i];
			if (ent->vuid == vuid) {
				free_conn_session_info_if_unused(conn);
				conn->session_info = ent->session_info;
				conn->read_only = ent->read_only;
				return(True);
			}
		}
	}

	if (!user_ok_token(session_info->unix_name,
			   session_info->info3->base.domain.string,
			   session_info->security_token, snum))
		return(False);

	readonly_share = is_share_read_only_for_token(
		session_info->unix_name,
		session_info->info3->base.domain.string,
		session_info->security_token,
		conn);

	if (!readonly_share &&
	    !share_access_check(session_info->security_token,
				lp_servicename(snum), FILE_WRITE_DATA,
				NULL)) {
		/* smb.conf allows r/w, but the security descriptor denies
		 * write. Fall back to looking at readonly. */
		readonly_share = True;
		DEBUG(5,("falling back to read-only access-evaluation due to "
			 "security descriptor\n"));
	}

	if (!share_access_check(session_info->security_token,
				lp_servicename(snum),
				readonly_share ?
				FILE_READ_DATA : FILE_WRITE_DATA,
				NULL)) {
		return False;
	}

	admin_user = token_contains_name_in_list(
		session_info->unix_name,
		session_info->info3->base.domain.string,
		NULL, session_info->security_token, lp_admin_users(snum));

	if (valid_vuid) {
		struct vuid_cache_entry *ent =
			&conn->vuid_cache.array[conn->vuid_cache.next_entry];

		conn->vuid_cache.next_entry =
			(conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE;

		TALLOC_FREE(ent->session_info);

		/*
		 * If force_user was set, all session_info's are based on the same
		 * username-based faked one.
		 */

		ent->session_info = copy_serverinfo(
			conn, conn->force_user ? conn->session_info : session_info);

		if (ent->session_info == NULL) {
			ent->vuid = UID_FIELD_INVALID;
			return false;
		}

		ent->vuid = vuid;
		ent->read_only = readonly_share;
		free_conn_session_info_if_unused(conn);
		conn->session_info = ent->session_info;
	}

	conn->read_only = readonly_share;
	if (admin_user) {
		DEBUG(2,("check_user_ok: user %s is an admin user. "
			"Setting uid as %d\n",
			conn->session_info->unix_name,
			sec_initial_uid() ));
		conn->session_info->utok.uid = sec_initial_uid();
	}

	return(True);
}
Ejemplo n.º 5
0
static bool check_user_ok(connection_struct *conn,
			uint64_t vuid,
			const struct auth_session_info *session_info,
			int snum)
{
	unsigned int i;
	bool readonly_share = false;
	bool admin_user = false;
	struct vuid_cache_entry *ent = NULL;
	uint32_t share_access = 0;
	NTSTATUS status;

	for (i=0; i<VUID_CACHE_SIZE; i++) {
		ent = &conn->vuid_cache->array[i];
		if (ent->vuid == vuid) {
			if (vuid == UID_FIELD_INVALID) {
				/*
				 * Slow path, we don't care
				 * about the array traversal.
				*/
				continue;
			}
			free_conn_session_info_if_unused(conn);
			conn->session_info = ent->session_info;
			conn->read_only = ent->read_only;
			conn->share_access = ent->share_access;
			return(True);
		}
	}

	status = check_user_share_access(conn,
					session_info,
					&share_access,
					&readonly_share);
	if (!NT_STATUS_IS_OK(status)) {
		return false;
	}

	admin_user = token_contains_name_in_list(
		session_info->unix_info->unix_name,
		session_info->info->domain_name,
		NULL, session_info->security_token, lp_admin_users(snum));

	ent = &conn->vuid_cache->array[conn->vuid_cache->next_entry];

	conn->vuid_cache->next_entry =
		(conn->vuid_cache->next_entry + 1) % VUID_CACHE_SIZE;

	TALLOC_FREE(ent->session_info);

	/*
	 * If force_user was set, all session_info's are based on the same
	 * username-based faked one.
	 */

	ent->session_info = copy_session_info(
		conn, conn->force_user ? conn->session_info : session_info);

	if (ent->session_info == NULL) {
		ent->vuid = UID_FIELD_INVALID;
		return false;
	}

	/*
	 * It's actually OK to call check_user_ok() with
	 * vuid == UID_FIELD_INVALID as called from change_to_user_by_session().
	 * All this will do is throw away one entry in the cache.
	 */

	ent->vuid = vuid;
	ent->read_only = readonly_share;
	ent->share_access = share_access;
	free_conn_session_info_if_unused(conn);
	conn->session_info = ent->session_info;
	if (vuid == UID_FIELD_INVALID) {
		/*
		 * Not strictly needed, just make it really
		 * clear this entry is actually an unused one.
		 */
		ent->read_only = false;
		ent->share_access = 0;
		ent->session_info = NULL;
	}

	conn->read_only = readonly_share;
	conn->share_access = share_access;

	if (admin_user) {
		DEBUG(2,("check_user_ok: user %s is an admin user. "
			"Setting uid as %d\n",
			conn->session_info->unix_info->unix_name,
			sec_initial_uid() ));
		conn->session_info->unix_token->uid = sec_initial_uid();
	}

	return(True);
}