]> jfr.im git - solanum.git/blobdiff - authd/provider.h
rb_connect: use SO_ERROR
[solanum.git] / authd / provider.h
index b04cf0093b9415d2511c0272b61b69f57e8f8f52..07b8a794a1508db11070d978f62b5353a01aeb2a 100644 (file)
 
 #define MAX_PROVIDERS 32       /* This should be enough */
 
-/* Registered providers */
-typedef enum
-{
-       PROVIDER_RDNS,
-       PROVIDER_IDENT,
-       PROVIDER_BLACKLIST,
-       PROVIDER_OPM,
-} provider_t;
-
 typedef enum
 {
        PROVIDER_STATUS_NOTRUN = 0,
@@ -45,6 +36,7 @@ typedef enum
 
 struct auth_client_data
 {
+       struct auth_provider *provider; /* Pointer back */
        time_t timeout;                 /* Provider timeout */
        void *data;                     /* Provider data */
        provider_status_t status;       /* Provider status */
@@ -52,7 +44,7 @@ struct auth_client_data
 
 struct auth_client
 {
-       uint16_t cid;                           /* Client ID */
+       uint32_t cid;                           /* Client ID */
 
        char l_ip[HOSTIPLEN + 1];               /* Listener IP address */
        uint16_t l_port;                        /* Listener port */
@@ -66,6 +58,8 @@ struct auth_client
        char username[USERLEN + 1];             /* Used for ident lookup */
 
        bool providers_starting;                /* Providers are still warming up */
+       bool providers_cancelled;               /* Providers are being cancelled */
+       unsigned int providers_active;          /* Number of active providers */
        unsigned int refcount;                  /* Held references */
 
        struct auth_client_data *data;          /* Provider-specific data */
@@ -76,8 +70,8 @@ typedef void (*provider_destroy_t)(void);
 
 typedef bool (*provider_start_t)(struct auth_client *);
 typedef void (*provider_cancel_t)(struct auth_client *);
-typedef void (*provider_timeout_t)(struct auth_client *);
-typedef void (*provider_complete_t)(struct auth_client *, provider_t);
+typedef void (*uint32_timeout_t)(struct auth_client *);
+typedef void (*provider_complete_t)(struct auth_client *, uint32_t);
 
 struct auth_stats_handler
 {
@@ -89,14 +83,17 @@ struct auth_provider
 {
        rb_dlink_node node;
 
-       provider_t id;
+       uint32_t id;                    /* Provider ID */
+
+       const char *name;               /* Name of the provider */
+       char letter;                    /* Letter used on reject, etc. */
 
        provider_init_t init;           /* Initalise the provider */
        provider_destroy_t destroy;     /* Terminate the provider */
 
        provider_start_t start;         /* Perform authentication */
        provider_cancel_t cancel;       /* Authentication cancelled */
-       provider_timeout_t timeout;     /* Timeout callback */
+       uint32_timeout_t timeout;       /* Timeout callback */
        provider_complete_t completed;  /* Callback for when other performers complete (think dependency chains) */
 
        struct auth_stats_handler stats_handler;
@@ -119,56 +116,77 @@ void init_providers(void);
 void destroy_providers(void);
 void cancel_providers(struct auth_client *auth);
 
-void provider_done(struct auth_client *auth, provider_t id);
-void accept_client(struct auth_client *auth, provider_t id);
-void reject_client(struct auth_client *auth, provider_t id, const char *data, const char *fmt, ...);
+void provider_done(struct auth_client *auth, uint32_t id);
+void accept_client(struct auth_client *auth);
+void reject_client(struct auth_client *auth, uint32_t id, const char *data, const char *fmt, ...);
 
 void handle_new_connection(int parc, char *parv[]);
 void handle_cancel_connection(int parc, char *parv[]);
+void auth_client_free(struct auth_client *auth);
 
-
-/* Get a provider's raw status */
-static inline provider_status_t
-get_provider_status(struct auth_client *auth, provider_t provider)
+static inline void
+auth_client_ref(struct auth_client *auth)
 {
-       return auth->data[provider].status;
+       auth->refcount++;
 }
 
-/* Set a provider's raw status */
 static inline void
-set_provider_status(struct auth_client *auth, provider_t provider, provider_status_t status)
+auth_client_unref(struct auth_client *auth)
 {
-       auth->data[provider].status = status;
+       auth->refcount--;
+       if (auth->refcount == 0)
+               auth_client_free(auth);
 }
 
-/* Set the provider as running
- * If you're doing asynchronous work call this */
-static inline void
-set_provider_running(struct auth_client *auth, provider_t provider)
+/* Get a provider by name */
+static inline struct auth_provider *
+find_provider(const char *name)
 {
-       auth->refcount++;
-       set_provider_status(auth, provider, PROVIDER_STATUS_RUNNING);
+       rb_dlink_node *ptr;
+
+       RB_DLINK_FOREACH(ptr, auth_providers.head)
+       {
+               struct auth_provider *provider = ptr->data;
+
+               if(strcasecmp(provider->name, name) == 0)
+                       return provider;
+       }
+
+       return NULL;
 }
 
-/* Provider is no longer operating on this auth client
- * You should use provider_done and not this */
-static inline void
-set_provider_done(struct auth_client *auth, provider_t provider)
+/* Get a provider's id by name */
+static inline bool
+get_provider_id(const char *name, uint32_t *id)
 {
-       auth->refcount--;
-       set_provider_status(auth, provider, PROVIDER_STATUS_DONE);
+       struct auth_provider *provider = find_provider(name);
+
+       if(provider != NULL)
+       {
+               *id = provider->id;
+               return true;
+       }
+       else
+               return false;
+}
+
+/* Get a provider's raw status */
+static inline provider_status_t
+get_provider_status(struct auth_client *auth, uint32_t provider)
+{
+       return auth->data[provider].status;
 }
 
 /* Check if provider is operating on this auth client */
 static inline bool
-is_provider_running(struct auth_client *auth, provider_t provider)
+is_provider_running(struct auth_client *auth, uint32_t provider)
 {
        return get_provider_status(auth, provider) == PROVIDER_STATUS_RUNNING;
 }
 
 /* Check if provider has finished on this client */
 static inline bool
-is_provider_done(struct auth_client *auth, provider_t provider)
+is_provider_done(struct auth_client *auth, uint32_t provider)
 {
        return get_provider_status(auth, provider) == PROVIDER_STATUS_DONE;
 }
@@ -177,7 +195,6 @@ is_provider_done(struct auth_client *auth, provider_t provider)
 static inline void *
 get_provider_data(struct auth_client *auth, uint32_t id)
 {
-       lrb_assert(id < rb_dlink_list_length(&auth_providers));
        return auth->data[id].data;
 }
 
@@ -185,7 +202,6 @@ get_provider_data(struct auth_client *auth, uint32_t id)
 static inline void
 set_provider_data(struct auth_client *auth, uint32_t id, void *data)
 {
-       lrb_assert(id < rb_dlink_list_length(&auth_providers));
        auth->data[id].data = data;
 }
 
@@ -194,7 +210,6 @@ set_provider_data(struct auth_client *auth, uint32_t id, void *data)
 static inline void
 set_provider_timeout_relative(struct auth_client *auth, uint32_t id, time_t timeout)
 {
-       lrb_assert(id < rb_dlink_list_length(&auth_providers));
        auth->data[id].timeout = timeout + rb_current_time();
 }
 
@@ -203,7 +218,6 @@ set_provider_timeout_relative(struct auth_client *auth, uint32_t id, time_t time
 static inline void
 set_provider_timeout_absolute(struct auth_client *auth, uint32_t id, time_t timeout)
 {
-       lrb_assert(id < rb_dlink_list_length(&auth_providers));
        auth->data[id].timeout = timeout;
 }
 
@@ -211,7 +225,6 @@ set_provider_timeout_absolute(struct auth_client *auth, uint32_t id, time_t time
 static inline time_t
 get_provider_timeout(struct auth_client *auth, uint32_t id)
 {
-       lrb_assert(id < rb_dlink_list_length(&auth_providers));
        return auth->data[id].timeout;
 }