Skip to content
Snippets Groups Projects
Commit 4d1c9414 authored by jwindley's avatar jwindley
Browse files

Add runtime argument descriptors

parent 76200ad6
No related branches found
No related tags found
No related merge requests found
......@@ -52,6 +52,7 @@ libcommon_la_SOURCES = \
slurm_protocol_defs.h \
util-net.c util-net.h \
slurm_auth.c slurm_auth.h \
arg_desc.c arg_desc.h \
macros.h \
$(elan_sources)
......
#include <string.h>
#include "src/common/arg_desc.h"
#include "src/common/xassert.h"
const int
arg_count( const arg_desc_t *desc )
{
int i;
if ( desc == NULL ) return 0;
i = 0;
while ( desc[ i ].name != NULL ) ++i;
return i;
}
const int
arg_idx_by_name( const arg_desc_t *desc, const char *name )
{
int i;
if ( desc == NULL ) return -1;
if ( name == NULL ) return -1;
for ( i = 0; desc[ i ].name != NULL; ++i ) {
if ( strcmp( desc[ i ].name, name ) == 0 ) {
return i;
}
}
return -1;
}
const char *
arg_name_by_idx( const arg_desc_t *desc, const int idx )
{
int i = idx;
if ( desc == NULL ) return NULL;
while ( i > 0 ) {
if ( desc[ i ].name != NULL ) --i;
}
return desc[ i ].name;
}
#ifndef __ARG_DESC_H__
#define __ARG_DESC_H__
/*
* An argument descriptor is a named positional parameter in an
* argv-like vector of arguments. An array of named parameters
* constitutes the descriptor, and the index (zero-based) in the
* array of the named parameter is also its index in the argument
* vector.
*
* The descriptor array must be terminated by an entry whose name
* is the NULL pointer.
*
* arg_desc_t arg_desc[] = {
* { "foo" },
* { "bar" },
* { NULL }
* };
*
* For vectors which are finalized at initialization, the receiving
* functions can call arg_idx_by_name() and cache the value in
* order to accelerate argument processing.
*
* For well-defined APIs containing explicit initialization routines,
* this can be done at initialization, as in
*
* void init( arg_desc_t *desc )
* {
* static_foo_idx = arg_idx_by_name( desc, "foo" );
* }
*
* void need_foo( void *argv[] )
* {
* foo_type foo = (foo_type) argv[ static_foo_idx ];
* ...
* }
*
* For vectors which may vary for each invocation of the function,
* it is best to pass the argument descriptor array as a first-class
* parameter to the function:
*
* void need_foo_dynamic( arg_desc_t *desc, void *argv[] )
* {
* int idx = arg_idx_by_name( desc, "foo" );
* foo_type foo = (foo_type) argv[ idx ];
* }
*/
typedef struct _arg_desc {
char *name;
} arg_desc_t;
/*
* Return the number of argument names in the descriptor.
*/
const int arg_count( const arg_desc_t *desc );
/*
* Return the index in the descriptor corresponding to the name.
*
* Returns -1 if the name can't be found.
*/
const int arg_idx_by_name( const arg_desc_t *desc, const char *name );
/*
* Return the name of the argument for the given index, or NULL if
* the index is invalid.
*/
const char *arg_name_by_idx( const arg_desc_t *desc, const int idx );
#endif /*__ARG_DESC_H__*/
......@@ -37,6 +37,7 @@
#include "src/common/slurm_auth.h"
#include "src/common/plugin.h"
#include "src/common/plugrack.h"
#include "src/common/arg_desc.h"
/*
* WARNING: Do not change the order of these fields or add additional
......@@ -45,9 +46,9 @@
* end of the structure.
*/
typedef struct slurm_auth_ops {
void * (*create) ( void );
void * (*create) ( void *argv[] );
int (*destroy) ( void *cred );
int (*verify) ( void *cred );
int (*verify) ( void *cred, void *argv[] );
uid_t (*get_uid) ( void *cred );
gid_t (*get_gid) ( void *cred );
int (*pack) ( void *cred, Buf buf );
......@@ -94,6 +95,15 @@ static pthread_mutex_t context_lock = PTHREAD_MUTEX_INITIALIZER;
static slurm_ctl_conf_t conf;
static pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER;
/*
* Order of advisory arguments passed to some of the plugins.
*/
static arg_desc_t auth_args[] = {
{ ARG_HOST_LIST },
{ ARG_TIMEOUT },
{ NULL }
};
static char *
get_plugin_dir( void )
......@@ -182,6 +192,44 @@ slurm_auth_get_ops( slurm_auth_context_t c )
return &c->ops;
}
const arg_desc_t *
slurm_auth_get_arg_desc( void )
{
return auth_args;
}
void **
slurm_auth_marshal_args( void *hosts, int timeout )
{
static int hostlist_idx = -1;
static int timeout_idx = -1;
static int count = sizeof( auth_args ) / sizeof( struct _arg_desc ) - 1;
void **argv;
/* Get indices from descriptor, if we haven't already. */
if ( ( hostlist_idx == -1 ) &&
( timeout_idx == -1 ) ) {
hostlist_idx = arg_idx_by_name( auth_args, ARG_HOST_LIST );
timeout_idx = arg_idx_by_name( auth_args, ARG_TIMEOUT );
}
argv = xmalloc( count * sizeof( void * ) );
/* Marshal host list. Don't quite know how to do this yet. */
argv[ hostlist_idx ] = hosts;
/* Marshal timeout. */
argv[ timeout_idx ] = (void *) timeout;
return argv;
}
void slurm_auth_free_args( void **argv )
{
xfree( argv );
}
slurm_auth_context_t
slurm_auth_context_create( const char *auth_type )
......@@ -298,12 +346,12 @@ slurm_auth_init( void )
*/
void *
g_slurm_auth_create( void )
g_slurm_auth_create( void *argv[] )
{
if ( slurm_auth_init() < 0 )
return NULL;
return (*(g_context->ops.create))();
return (*(g_context->ops.create))( argv );
}
int
......@@ -316,12 +364,12 @@ g_slurm_auth_destroy( void *cred )
}
int
g_slurm_auth_verify( void *cred )
g_slurm_auth_verify( void *cred, void *argv[] )
{
if ( slurm_auth_init() < 0 )
return SLURM_ERROR;
return (*(g_context->ops.verify))( cred );
return (*(g_context->ops.verify))( cred, argv );
}
uid_t
......
......@@ -44,6 +44,7 @@
#include "src/common/plugrack.h"
#include "src/common/pack.h"
#include "src/common/arg_desc.h"
/*
* This API operates on a global authentication
......@@ -62,17 +63,49 @@
*
*/
/*
* General error codes that plugins (or the plugin system) can
* generate. Plugins may produce additional codes starting with
* SLURM_AUTH_FIRST_LOCAL_ERROR. They are responsible for providing
* text messages to accompany the codes. This API resolves string
* messages for these codes.
*/
enum {
SLURM_AUTH_NOPLUGIN,
SLURM_AUTH_BADARG,
SLURM_AUTH_MEMORY,
SLURM_AUTH_NOUSER,
SLURM_AUTH_INVALID,
SLURM_AUTH_MISMATCH,
SLURM_AUTH_FIRST_LOCAL_ERROR /* Always keep me last. */
SLURM_AUTH_NOPLUGIN, /* No plugin for this type. */
SLURM_AUTH_BADARG, /* Bad argument to an API func. */
SLURM_AUTH_MEMORY, /* Problem allocating memory. */
SLURM_AUTH_NOUSER, /* User not defined on host. */
SLURM_AUTH_INVALID, /* Invalid credential. */
SLURM_AUTH_MISMATCH, /* Credential from another plugin. */
SLURM_AUTH_FIRST_LOCAL_ERROR /* Always keep me last. */
};
/*
* Text labels for advisory arguments passed to plugin functions.
* Use these labels rather than string literals in order to avoid
* misspellings.
*/
#define ARG_HOST_LIST "HostList"
#define ARG_TIMEOUT "Timeout"
/*
* Return the argument descriptor for the argument vectors in the
* plugin API.
*/
const arg_desc_t *slurm_auth_get_arg_desc( void );
/*
* Marshal the arguments into a generic argument vector according to
* the authentication argument layout.
*/
void **slurm_auth_marshal_args( void *hosts, int timeout );
/*
* Free an argument list created by slurm_auth_marshal_args().
*/
void slurm_auth_free_args( void **args );
/*
* SLURM authentication context opaque type.
*/
......@@ -109,9 +142,9 @@ int slurm_auth_init( void );
/*
* Static bindings for the global authentication context.
*/
void *g_slurm_auth_create( void );
void *g_slurm_auth_create( void *argv[] );
int g_slurm_auth_destroy( void *cred );
int g_slurm_auth_verify( void *cred );
int g_slurm_auth_verify( void *cred, void *argv[] );
uid_t g_slurm_auth_get_uid( void *cred );
gid_t g_slurm_auth_get_gid( void *cred );
int g_slurm_auth_pack( void *cred, Buf buf );
......
......@@ -334,6 +334,7 @@ int slurm_receive_msg(slurm_fd open_fd, slurm_msg_t * msg)
int rc;
void *auth_cred;
Buf buffer;
void **argv;
buftemp = xmalloc(SLURM_PROTOCOL_MAX_MESSAGE_BUFFER_SIZE);
if ((rc = _slurm_msg_recvfrom(open_fd, buftemp,
......@@ -365,13 +366,21 @@ int slurm_receive_msg(slurm_fd open_fd, slurm_msg_t * msg)
}
/* verify credentials */
if ((rc = g_slurm_auth_verify(auth_cred)) != SLURM_SUCCESS) {
argv = slurm_auth_marshal_args( NULL, 2 );
if ( argv == NULL ) {
(void) g_slurm_auth_destroy( auth_cred );
free_buf( buffer );
slurm_seterrno_ret( SLURM_PROTOCOL_AUTHENTICATION_ERROR );
}
rc = g_slurm_auth_verify( auth_cred, argv );
slurm_auth_free_args( argv );
if ( rc != SLURM_SUCCESS) {
error( "authentication: %s ",
g_slurm_auth_errstr( g_slurm_auth_errno( auth_cred ) ) );
(void) g_slurm_auth_destroy(auth_cred);
free_buf(buffer);
slurm_seterrno_ret(SLURM_PROTOCOL_AUTHENTICATION_ERROR);
}
}
/* unpack msg body */
msg->msg_type = header.msg_type;
......@@ -430,9 +439,16 @@ int slurm_send_node_msg(slurm_fd open_fd, slurm_msg_t * msg)
unsigned int msg_len, tmp_len;
Buf buffer;
void *auth_cred;
void **argv;
/* initialize header */
auth_cred = g_slurm_auth_create();
argv = slurm_auth_marshal_args( NULL, 1 );
if ( argv == NULL ) {
error( "cannot marshal arguments to create credential" );
return SLURM_PROTOCOL_AUTHENTICATION_ERROR;
}
auth_cred = g_slurm_auth_create( argv );
slurm_auth_free_args( argv );
if ( auth_cred == NULL ) {
error( "authentication: %s",
g_slurm_auth_errstr( g_slurm_auth_errno( NULL ) ) );
......
......@@ -69,13 +69,20 @@
#include "src/common/xassert.h"
#include "src/common/pack.h"
#include "src/common/log.h"
#include "src/common/arg_desc.h"
const char plugin_name[] = "Brett Chun's authd authentication plugin";
const char plugin_type[] = "auth/authd";
const uint32_t plugin_version = 90;
/* Default life span of an authd credential in seconds. */
static const int authd_ttl = 2;
/*
* Where to find the timeout in the argument vector. This is set
* during initialization and should not change.
*/
static int timeout_idx = -1;
/* Default timeout. */
static const int AUTHD_TTL = 2;
typedef struct _slurm_auth_credential {
credentials cred;
......@@ -231,22 +238,47 @@ slurm_auth_verify_signature( credentials *cred, signature *sig )
return rc_error;
}
int init( void )
{
const arg_desc_t *desc;
verbose( "authd authenticaiton module initializing" );
if ( ( desc = slurm_auth_get_arg_desc() ) == NULL ) {
error( "unable to query SLURM for argument vector layout" );
return SLURM_ERROR;
}
if ( ( timeout_idx = arg_idx_by_name( desc, ARG_TIMEOUT ) ) < 0 ) {
error( "Required argument 'Timeout' not provided" );
return SLURM_ERROR;
}
return SLURM_SUCCESS;
}
slurm_auth_credential_t *
slurm_auth_create( void )
slurm_auth_create( void *argv[] )
{
int ttl = authd_ttl;
slurm_auth_credential_t *cred =
(slurm_auth_credential_t *)
int ttl;
slurm_auth_credential_t *cred;
if ( argv == NULL ) {
plugin_errno = SLURM_AUTH_MEMORY;
return NULL;
}
cred = (slurm_auth_credential_t *)
xmalloc( sizeof( slurm_auth_credential_t ) );
cred->cr_errno = SLURM_SUCCESS;
/* Initialize credential with our user and group. */
cred->cred.uid = geteuid();
cred->cred.gid = getegid();
/* Set a valid time interval. */
cred->cred.valid_from = time( NULL );
ttl = timeout_idx >= 0 ? (int) argv[ timeout_idx ] : AUTHD_TTL;
/*
* In debug mode read the time-to-live from an environment
* variable.
......@@ -260,7 +292,7 @@ slurm_auth_create( void )
}
}
#endif /*NDEBUG*/
cred->cred.valid_to = cred->cred.valid_from + ttl;
/* Sign the credential. */
......@@ -285,12 +317,12 @@ slurm_auth_destroy( slurm_auth_credential_t *cred )
}
int
slurm_auth_verify( slurm_auth_credential_t *cred )
slurm_auth_verify( slurm_auth_credential_t *cred, void *argv[] )
{
int rc;
time_t now;
if ( cred == NULL ) {
if ( ( cred == NULL ) || ( argv == NULL ) ) {
plugin_errno = SLURM_AUTH_BADARG;
return SLURM_ERROR;
}
......
......@@ -62,6 +62,7 @@
#include "src/common/pack.h"
#include "src/common/log.h"
#include "src/common/slurm_auth.h"
#include "src/common/arg_desc.h"
const char plugin_name[] = "auth plugin for Chris Dunlap's Munge";
const char plugin_type[] = "auth/munge";
......@@ -69,6 +70,8 @@ const uint32_t plugin_version = 10;
static int plugin_errno = SLURM_SUCCESS;
static int host_list_idx = -1;
enum {
SLURM_AUTH_UNPACK = SLURM_AUTH_FIRST_LOCAL_ERROR
};
......@@ -120,12 +123,10 @@ _decode_cred(char *m, slurm_auth_credential_t *c)
int init ( void )
{
/*
* Perhaps we could init a global context here?
* Do nothing for now.
*
*/
return 0;
host_list_idx = arg_idx_by_name( slurm_auth_get_arg_desc(),
ARG_HOST_LIST );
if ( host_list_idx == -1 ) return SLURM_ERROR;
return SLURM_SUCCESS;
}
......@@ -135,7 +136,7 @@ int init ( void )
* data at this time is implementation-dependent.
*/
slurm_auth_credential_t *
slurm_auth_create( void )
slurm_auth_create( void *argv[] )
{
slurm_auth_credential_t *cred = NULL;
munge_err_t e = EMUNGE_SUCCESS;
......@@ -189,7 +190,7 @@ slurm_auth_destroy( slurm_auth_credential_t *cred )
* Return SLURM_SUCCESS if the credential is in order and valid.
*/
int
slurm_auth_verify( slurm_auth_credential_t *c )
slurm_auth_verify( slurm_auth_credential_t *c, void *argv[] )
{
if (!c) {
plugin_errno = SLURM_AUTH_BADARG;
......
......@@ -146,9 +146,10 @@ enum {
* init() is called when the plugin is loaded, before any other functions
* are called. Put global initialization here.
*/
void init ( void )
int init ( void )
{
debug("authentication==none");
return SLURM_SUCCESS;
}
/*
......@@ -161,7 +162,7 @@ void init ( void )
* NULL if it cannot allocate a credential.
*/
slurm_auth_credential_t *
slurm_auth_create( void )
slurm_auth_create( void *argv[] )
{
slurm_auth_credential_t *cred;
......@@ -194,7 +195,7 @@ slurm_auth_destroy( slurm_auth_credential_t *cred )
* Return SLURM_SUCCESS if the credential is in order and valid.
*/
int
slurm_auth_verify( slurm_auth_credential_t *cred )
slurm_auth_verify( slurm_auth_credential_t *cred, void *argv[] )
{
return SLURM_SUCCESS;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment