static
int
globus_gfs_acl_test_authorize(
    void *                              out_handle,
    const char *                        action,
    const char *                        object,
    globus_gfs_acl_info_t *             acl_info,
    globus_gfs_acl_handle_t             acl_handle,
    globus_result_t *                   out_res)
{
    GlobusGFSName(globus_gfs_acl_test_authorize);
    GlobusGFSDebugEnter();

    if(1 || strncmp(object, "/path/you/allow", 5) == 0)
    {
        *out_res = GLOBUS_SUCCESS;
    }
    else
    {
        *out_res = GlobusGFSErrorGeneric("No soup for you.");
    }
    
    globus_gfs_acl_authorized_finished(acl_handle, *out_res);

    GlobusGFSDebugExit();
    return GLOBUS_GFS_ACL_WOULD_BLOCK;
}
static
int
globus_gfs_acl_test_init(
    void **                             out_handle,
    globus_gfs_acl_info_t *             acl_info,
    globus_gfs_acl_handle_t             acl_handle,
    globus_result_t *                   out_res)
{
    GlobusGFSName(globus_gfs_acl_test_init);
    GlobusGFSDebugEnter();

    if(1 || (acl_info->subject && 
        strcmp(acl_info->subject, "subject you allow") == 0))
    {
        *out_res = GLOBUS_SUCCESS;
    }
    else
    {
        *out_res = GlobusGFSErrorGeneric("No soup for you.");
    }        

    globus_gfs_acl_authorized_finished(acl_handle, *out_res);

    GlobusGFSDebugExit();
    return GLOBUS_GFS_ACL_WOULD_BLOCK;
}
Esempio n. 3
0
globus_result_t
stat_populate(char              * Name,
              int                 Type,
              int                 LinkCount,
              uint64_t            Size,
              char              * Owner,
              char              * ModTime,
              globus_gfs_stat_t * GFSStat)
{
	GlobusGFSName(stat_populate);

	memset(GFSStat, 0, sizeof(globus_gfs_stat_t));

	GFSStat->mode  = Type | S_IRWXU;
	GFSStat->nlink = LinkCount;
// XXX Inodes not supported
	GFSStat->ino   = 0xDEADBEEF;
// XXX UIDs not supported
//	XXX GFSStat->uid   = HpssStat->st_uid;
	GFSStat->gid   = 0; // Groups not supported
	GFSStat->dev   = 0;
	GFSStat->size  = Size;
	GFSStat->name  = globus_libc_strdup(Name);

	if (!ModTime)
	{
		GFSStat->atime = 0;
		GFSStat->mtime = 0;
		GFSStat->ctime = 0;
	} else
	{
		struct tm t;
		memset(&t, 0, sizeof(t));

		int ret = sscanf(ModTime, "%d-%d-%dT%d:%d:%d.", &t.tm_year,
		                                                &t.tm_mon,
		                                                &t.tm_mday,
		                                                &t.tm_hour,
		                                                &t.tm_min,
		                                                &t.tm_sec);
		if (ret != 6)
			return GlobusGFSErrorGeneric("Invalid time string");

		t.tm_year -= 1900;
		time_t time_of_day = mktime(&t);
		GFSStat->atime = time_of_day;
		GFSStat->mtime = time_of_day;
		GFSStat->ctime = time_of_day;
	}

	return GLOBUS_SUCCESS;
}
Esempio n. 4
0
void
dsi_send(globus_gfs_operation_t       Operation,
         globus_gfs_transfer_info_t * TransferInfo,
         void                       * UserArg)
{
	globus_result_t result = GLOBUS_SUCCESS;

	GlobusGFSName(dsi_send);

	if (dsi_partial_transfer(TransferInfo) || dsi_restart_transfer(TransferInfo))
	{
		result = GlobusGFSErrorGeneric("Non-zero offsets are not supported");
		globus_gridftp_server_finished_transfer(Operation, result);
		return;
	}

	retr(UserArg, Operation, TransferInfo);
}
Esempio n. 5
0
globus_result_t
stat_entries(ds3_client        * Client,
             char              * Path,
             int                 FileOnly,
             int                 MaxEntries,
             globus_gfs_stat_t * GFSStatArray,
             int               * CountOut,
             stat_state_t      * State)
{
	globus_result_t result = GLOBUS_SUCCESS;
	int i = 0;
	int expanding_search = 0;

	GlobusGFSName(stat_entries);

	if (!State->_bucket_name && !State->_object_name)
		path_split(Path, &State->_bucket_name, &State->_object_name);

	if (!State->_service_response)
	{
		result = gds3_get_service(Client, &State->_service_response);
		if (result != GLOBUS_SUCCESS)
			return result;
	}

	*CountOut = 0;

	/* No bucket_name means it _is_ '/' */
	if (!State->_bucket_name)
	{
		if (FileOnly)
		{
			/* Return a stat of only '/'. */
			result = stat_populate("/",
			                       S_IFDIR,
			                       State->_service_response->num_buckets + 2,
			                       1024,
			                       ds3_str_value(State->_service_response->owner->name),
			                       NULL,
			                       &GFSStatArray[(*CountOut)++]);
			State->_complete = 1;
			return result;
		} else
		{
			/* Return the contents of '/'. */
			if (State->_index++ == 0)
			{
				result = stat_populate(".",
				                       S_IFDIR,
				                       State->_service_response->num_buckets + 2,
				                       1024,
				                       ds3_str_value(State->_service_response->owner->name),
				                       NULL, // XXX no modify time
				                       &GFSStatArray[(*CountOut)++]);

				if (result != GLOBUS_SUCCESS || *CountOut == MaxEntries)
					return result;
			}

			if (State->_index++ == 1)
			{
				result = stat_populate("..",
				                       S_IFDIR,
				                       State->_service_response->num_buckets + 2,
				                       1024,
				                       ds3_str_value(State->_service_response->owner->name),
				                       NULL, // XXX no modify time
				                       &GFSStatArray[(*CountOut)++]);

				if (State->_service_response->num_buckets == 0)
					State->_complete = 1;

				if (result != GLOBUS_SUCCESS || *CountOut == MaxEntries)
					return result;
			}

			for (i = State->_index-2;
			     i < State->_service_response->num_buckets && *CountOut < MaxEntries;
			     i++)
			{
				result = stat_populate(ds3_str_value(State->_service_response->buckets[i].name),
				                       S_IFDIR,
				                       2,
				                       1024,
				                       ds3_str_value(State->_service_response->owner->name),
				                       ds3_str_value(State->_service_response->buckets[i].creation_date),
				                       &GFSStatArray[(*CountOut)++]);
				if (result != GLOBUS_SUCCESS)
					return result;
			}
			State->_complete = (i == State->_service_response->num_buckets);
			return result;
		}
	}

	/* No object_name means it is _in_ '/' */
	if (!State->_object_name && FileOnly)
	{
		for (i = 0;
		     i < State->_service_response->num_buckets;
		     i++)
		{
			if (strcmp(State->_bucket_name, ds3_str_value(State->_service_response->buckets[i].name)) == 0)
			{
				result = stat_populate(ds3_str_value(State->_service_response->buckets[i].name),
				                       S_IFDIR,
				                       2,
				                       1024,
				                       ds3_str_value(State->_service_response->owner->name),
				                       ds3_str_value(State->_service_response->buckets[i].creation_date),
				                       &GFSStatArray[(*CountOut)++]);
				State->_complete = 1;
				return result;
			}
		}

		return GlobusGFSErrorGeneric("No such file or directory");
	}

	/* Let's find this object. */
	if (State->_object_name && State->_object_name[strlen(State->_object_name)-1] != '/')
	{
		do
		{
			/* Get the next response. */
			if (!State->_bucket_response)
			{
				result = gds3_get_bucket(Client,
				                         State->_bucket_name,
				                         &State->_bucket_response,
				                         "/", /* Delimiter */
				                         State->_object_name,
				                         State->_marker,
				                         MaxEntries);
				if (result)
					return result;
			}

			/* If it is an object... */
			for (i = 0; i < State->_bucket_response->num_objects; i++)
			{
				if (strcmp(State->_object_name, ds3_str_value(State->_bucket_response->objects[i].name)) == 0)
				{
					char * last_modified = NULL;
					if (State->_bucket_response->objects[i].last_modified)
						last_modified = ds3_str_value(State->_bucket_response->objects[i].last_modified);
					result = stat_populate(basename(State->_object_name),
					                       S_IFREG,
					                       1,
					                       State->_bucket_response->objects[i].size,
					                       ds3_str_value(State->_bucket_response->objects[i].owner->name),
					                       last_modified,
					                       &GFSStatArray[(*CountOut)++]);
					State->_complete = 1;
					return result;
				}
			}

			/* If it is a directory... */
			for (i = 0; i < State->_bucket_response->num_common_prefixes; i++)
			{
				if (strncmp(State->_object_name,
				            ds3_str_value(State->_bucket_response->common_prefixes[i]),
				            ds3_str_size(State->_bucket_response->common_prefixes[i])-1) == 0 &&
				    State->_bucket_response->common_prefixes[i]->value[
				                      State->_bucket_response->common_prefixes[i]->size-1] == '/')
				{
					/* If we do not need to expand the directory... */
					if (FileOnly)
					{
						result = stat_populate(basename(State->_object_name),
						                       S_IFDIR,
						                       2,
						                       1024,
						                       ds3_str_value(State->_service_response->owner->name),
						                       NULL,
						                       &GFSStatArray[(*CountOut)++]);
						State->_complete = 1;
						return result;
					} else
					{
						char * new_object_name = malloc(strlen(State->_object_name)+2);
						sprintf(new_object_name, "%s/", State->_object_name);
						free(State->_object_name);
						State->_object_name = new_object_name;

						if (State->_bucket_response)
							ds3_free_bucket_response(State->_bucket_response);
						State->_bucket_response = NULL;
						if (State->_marker)
							free(State->_marker);
						State->_index = 0;

						expanding_search = 1;
						break;
					}
				}
			}
		} while (State->_marker);

		/* We could not find it. */
		if (!expanding_search)
			return GlobusGFSErrorGeneric("No such file or directory");
	}

	do
	{
		/* First pass. */
		if (!State->_bucket_response && !State->_index)
		{
			result = stat_populate(".",
			                       S_IFDIR,
			                       2,
			                       1024,
			                       ds3_str_value(State->_service_response->owner->name),
			                       NULL, // XXX no modify time
			                       &GFSStatArray[(*CountOut)++]);

			if (result != GLOBUS_SUCCESS)
				return result;

			result = stat_populate("..",
			                       S_IFDIR,
			                       2,
			                       1024,
			                       ds3_str_value(State->_service_response->owner->name),
			                       NULL, // XXX no modify time
			                       &GFSStatArray[(*CountOut)++]);

			if (result != GLOBUS_SUCCESS)
				return result;
		}

		/* Get the next response. */
		if (!State->_bucket_response)
		{
			result = gds3_get_bucket(Client,
			                         State->_bucket_name,
			                         &State->_bucket_response,
			                         "/", /* Delimiter */
			                         State->_object_name,
			                         State->_marker,
			                         MaxEntries);
			if (result)
				return result;

			State->_index = 0;
		}

		for (i = State->_index; i < State->_bucket_response->num_objects; i++, State->_index++)
		{
			if (State->_object_name && strcmp(State->_bucket_response->objects[i].name->value, State->_object_name) == 0)
				continue;

			char * last_modified = NULL;
			if (State->_bucket_response->objects[i].last_modified)
				last_modified = ds3_str_value(State->_bucket_response->objects[i].last_modified);
			result = stat_populate(State->_bucket_response->objects[i].name->value + (State->_object_name ? strlen(State->_object_name) : 0),
			                       S_IFREG,
			                       1,
			                       State->_bucket_response->objects[i].size,
			                       ds3_str_value(State->_bucket_response->objects[i].owner->name),
			                       last_modified,
			                       &GFSStatArray[(*CountOut)++]);

			if (result != GLOBUS_SUCCESS || *CountOut == MaxEntries)
				return result;
		}

		for (i = State->_index - State->_bucket_response->num_objects;
		     i < State->_bucket_response->num_common_prefixes; 
		     i++, State->_index++)
		{
			char * entry = malloc(State->_bucket_response->common_prefixes[i]->size);
			snprintf(entry,
			         State->_bucket_response->common_prefixes[i]->size, 
			         "%s", 
			         State->_bucket_response->common_prefixes[i]->value);
			result = stat_populate(entry + (State->_object_name ? strlen(State->_object_name) : 0),
			                       S_IFDIR,
			                       2,
			                       1024,
			                       ds3_str_value(State->_service_response->owner->name),
			                       NULL,
			                       &GFSStatArray[(*CountOut)++]);
			free(entry);
			if (result != GLOBUS_SUCCESS || *CountOut == MaxEntries)
				return result;
		}

		ds3_free_bucket_response(State->_bucket_response);
		State->_bucket_response = NULL;

	} while (State->_marker);

	State->_complete = 1;
	return result;
}
static void
site_usage(globus_gfs_operation_t op,
           globus_gfs_command_info_t *cmd_info)
{
    GlobusGFSName(site_usage);

    int argc = 0;
    char **argv;

    globus_result_t result = globus_gridftp_server_query_op_info(
        op,
        cmd_info->op_info,
        GLOBUS_GFS_OP_INFO_CMD_ARGS,
        &argv,
        &argc
        );
    if (result != GLOBUS_SUCCESS)
    {
        result = GlobusGFSErrorGeneric("Incorrect invocation of SITE USAGE command");
        globus_gridftp_server_finished_command(op, result, "550 Incorrect invocation of SITE USAGE.\r\n");
        return;
    }
    if ((argc != 3) && (argc != 5))
    {
        result = GlobusGFSErrorGeneric("Incorrect number of arguments to SITE USAGE command");
        globus_gridftp_server_finished_command(op, result, "550 Incorrect number of arguments to SITE USAGE command.\r\n");
        return;
    }
    const char *token_name = "default";
    if ((argc == 5) && strcasecmp("TOKEN", argv[2]))
    {
        result = GlobusGFSErrorGeneric("Incorrect format for SITE USAGE command");
        globus_gridftp_server_finished_command(op, result, "550 Expected format: SITE USAGE [TOKEN name] path.\r\n");
        return;
    }
    if (argc == 5) {
        token_name = argv[3];
    }

    const char *script_pathname = getenv("OSG_SITE_USAGE_SCRIPT");
    if (!script_pathname)
    {
        result = GlobusGFSErrorGeneric("Site usage script not configured");
        globus_gridftp_server_finished_command(op, result, "550 Server is not configured to provide site usage.\r\n");
        return;
    }
    char cmd[256];
    snprintf(cmd, 256, "%s %s %s", script_pathname, token_name, cmd_info->pathname);
    cmd[255] = '\0';
    FILE *fp = popen(cmd, "r");
    if (fp == NULL) {
        result = GlobusGFSErrorSystemError("usage script", errno);
        globus_gridftp_server_finished_command(op, result, "550 Server failed to start usage query.\r\n");
        return;
    }
    char output[1024];
    while (fgets(output, 1024, fp) != NULL) {}

    int status = pclose(fp);
    if ((status == -1) || (status > 0))
    {
        if (status == -1) {result = GlobusGFSErrorSystemError("Usage script failed", errno);}
        else {result = GlobusGFSErrorGeneric("Site usage script failed");}
        globus_gridftp_server_finished_command(op, result, "550 Server usage query failed.\r\n");
        return;
    }
    char *newline_char = strchr(output, '\n');
    if (newline_char) {*newline_char = '\0';}

    long long usage, free, total;
    int output_count = sscanf(output, "%lld %lld %lld", &usage, &free, &total);
    if (output_count < 2)
    {
        result = GlobusGFSErrorGeneric("Invalid output from site usage script");
        globus_gridftp_server_finished_command(op, result, "550 Invalid output from site usage script.\r\n");
        return;
    }
    if (output_count == 2) {total = usage + free;}

    char final_output[1024];
    snprintf(final_output, 1024, "250 USAGE %lld FREE %lld TOTAL %lld\r\n", usage, free, total);
    final_output[1023] = '\0';
    globus_gridftp_server_finished_command(op, result, final_output);
}
/*
 * Authenticate to HPSS.
 */
static globus_result_t
session_auth_to_hpss(session_handle_t * SessionHandle)
{
	int                  uid                      = -1;
	int                  retval                   = 0;
	char               * login_name               = NULL;
	char               * authn_mech               = NULL;
	char               * config_authenticator_str = NULL;
	char               * actual_authenticator_val = NULL;
	globus_result_t      result                   = GLOBUS_SUCCESS;
	hpss_rpc_auth_type_t auth_type;
	api_config_t         api_config;
	mode_t               old_mask;

	GlobusGFSName(__func__);
	GlobusGFSHpssDebugEnter();

	/* Get the login name of the priviledged user. */
	login_name = config_get_login_name(SessionHandle->ConfigHandle);
	if (login_name == NULL)
	{
		result = GlobusGFSErrorGeneric("LoginName missing from config file");
		goto cleanup;
	}

	/* Get the authentication mechanism (unix, krb5, etc) */
	authn_mech = config_get_authentication_mech(SessionHandle->ConfigHandle);
	if (!authn_mech)
	{
		result = GlobusGFSErrorGeneric("AuthenticationMech missing from config file");
		goto cleanup;
	}

	/* Get the authenticator. */
	config_authenticator_str = config_get_authenticator(SessionHandle->ConfigHandle);
	if (!config_authenticator_str)
	{
		result = GlobusGFSErrorGeneric("Authenticator missing from config file");
		goto cleanup;
	}

	/*
	 * Get the current HPSS client configuration.
	 */
	retval = hpss_GetConfiguration(&api_config);
	if (retval != 0)
	{
		result = GlobusGFSErrorSystemError("hpss_GetConfiguration", -retval);
		goto cleanup;
	}

	/* Translate the authentication mechanism. */
	retval = hpss_AuthnMechTypeFromString(authn_mech, &api_config.AuthnMech);
	if (retval != HPSS_E_NOERROR)
	{
		result = GlobusGFSErrorGeneric("Bad value for config value AuthenticationMech");
		goto cleanup;
	}

	/* Parse the authenticator. */
	retval = hpss_ParseAuthString(config_authenticator_str, 
	                              &api_config.AuthnMech, 
	                              &auth_type, 
	                              (void **)&actual_authenticator_val);
	if (retval != HPSS_E_NOERROR)
	{
		actual_authenticator_val = NULL;
		result = GlobusGFSErrorGeneric("Bad value for config value Authenticator");
		goto cleanup;
	}

	/* Now set the current HPSS client configuration. */
	api_config.Flags  =  API_USE_CONFIG;
	retval = hpss_SetConfiguration(&api_config);
	if (retval != 0)
	{
		result = GlobusGFSErrorSystemError("hpss_SetConfiguration", -retval);
		goto cleanup;
	}

	/* Now log into HPSS using our configured 'super user' */
	retval = hpss_SetLoginCred(login_name,
	                           api_config.AuthnMech,
	                           hpss_rpc_cred_client,
	                           auth_type,
	                           actual_authenticator_val);
	if (retval != 0)
	{
		result = GlobusGFSErrorSystemError("hpss_SetLoginCred", -retval);
		goto cleanup;
	}

	/*
	 * Now we need to masquerade as this user on our HPSS connection.
	 */

	/* Get the user's UID. */
	result = misc_username_to_uid(SessionHandle->SessionInfo.username, &uid);
	if (result != GLOBUS_SUCCESS)
		goto cleanup;

	/*
	 * Deterine the current umask.
	 */
	old_mask = hpss_Umask(0);
	hpss_Umask(old_mask);

	/*
	 * Now masquerade as this user. This will lookup uid in our realm and
	 * set our credential to that user. The lookup is determined by the
	 * /var/hpss/etc/auth.conf, authz.conf files.
	 */
	retval = hpss_LoadDefaultThreadState(uid, old_mask, NULL);
	if(retval != 0)
	{
		result = GlobusGFSErrorSystemError("hpss_LoadDefaultThreadState", -retval);
		goto cleanup;
	}

cleanup:
	if (actual_authenticator_val)
		free(actual_authenticator_val);

	if (result != GLOBUS_SUCCESS)
	{
		GlobusGFSHpssDebugExitWithError();
		return result;
	}

	GlobusGFSHpssDebugExit();
	return GLOBUS_SUCCESS;
}