root/usr.sbin/ldapd/schema.h
/*      $OpenBSD: schema.h,v 1.7 2010/11/04 15:35:00 martinh Exp $ */

/*
 * Copyright (c) 2010 Martin Hedenfalk <martinh@openbsd.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef _schema_h_
#define _schema_h_

#define OBJ_NAME(obj)    ((obj)->names ? SLIST_FIRST((obj)->names)->name : \
                                (obj)->oid)
#define ATTR_NAME(at)    OBJ_NAME(at)

enum usage {
        USAGE_USER_APP,
        USAGE_DIR_OP,           /* operational attribute */
        USAGE_DIST_OP,          /* operational attribute */
        USAGE_DSA_OP            /* operational attribute */
};

enum match_rule_type {
        MATCH_EQUALITY,
        MATCH_ORDERING,
        MATCH_SUBSTR,
};

struct name {
        SLIST_ENTRY(name)        next;
        char                    *name;
};
SLIST_HEAD(name_list, name);

struct schema;
struct syntax {
        char                    *oid;
        char                    *desc;
        int                     (*is_valid)(struct schema *schema, char *value,
                                        size_t len);
};

struct match_rule
{
        char                    *oid;
        char                    *name;
        enum match_rule_type     type;
        int                     (*prepare)(char *value, size_t len);
        const char              *syntax_oid;
        const char              **alt_syntax_oids;
};

struct attr_type {
        RB_ENTRY(attr_type)      link;
        char                    *oid;
        struct name_list        *names;
        char                    *desc;
        int                      obsolete;
        struct attr_type        *sup;
        const struct match_rule *equality;
        const struct match_rule *ordering;
        const struct match_rule *substr;
        const struct syntax     *syntax;
        int                      single;
        int                      collective;
        int                      immutable;     /* no-user-modification */
        enum usage               usage;
};
RB_HEAD(attr_type_tree, attr_type);
RB_PROTOTYPE(attr_type_tree, attr_type, link, attr_oid_cmp);

struct attr_ptr {
        SLIST_ENTRY(attr_ptr)    next;
        struct attr_type        *attr_type;
};
SLIST_HEAD(attr_list, attr_ptr);

enum object_kind {
        KIND_ABSTRACT,
        KIND_STRUCTURAL,
        KIND_AUXILIARY
};

struct object;
struct obj_ptr {
        SLIST_ENTRY(obj_ptr)     next;
        struct object           *object;
};
SLIST_HEAD(obj_list, obj_ptr);

struct object {
        RB_ENTRY(object)         link;
        char                    *oid;
        struct name_list        *names;
        char                    *desc;
        int                      obsolete;
        struct obj_list         *sup;
        enum object_kind         kind;
        struct attr_list        *must;
        struct attr_list        *may;
};
RB_HEAD(object_tree, object);
RB_PROTOTYPE(object_tree, object, link, obj_oid_cmp);

struct oidname {
        RB_ENTRY(oidname)        link;
        const char              *on_name;
#define on_attr_type             on_ptr.ou_attr_type
#define on_object                on_ptr.ou_object
        union   {
                struct attr_type        *ou_attr_type;
                struct object           *ou_object;
        } on_ptr;
};
RB_HEAD(oidname_tree, oidname);
RB_PROTOTYPE(oidname_tree, oidname, link, oidname_cmp);

struct symoid {
        RB_ENTRY(symoid)         link;
        char                    *name;          /* symbolic name */
        char                    *oid;
};
RB_HEAD(symoid_tree, symoid);
RB_PROTOTYPE(symoid_tree, symoid, link, symoid_cmp);

#define SCHEMA_MAXPUSHBACK      128

struct schema
{
        struct attr_type_tree    attr_types;
        struct oidname_tree      attr_names;
        struct object_tree       objects;
        struct oidname_tree      object_names;
        struct symoid_tree       symbolic_oids;

        FILE                    *fp;
        const char              *filename;
        char                     pushback_buffer[SCHEMA_MAXPUSHBACK];
        int                      pushback_index;
        int                      lineno;
        int                      error;
};

struct schema           *schema_new(void);
int                      schema_parse(struct schema *schema,
                            const char *filename);
int                      schema_dump_object(struct object *obj,
                            char *buf, size_t size);
int                      schema_dump_attribute(struct attr_type *obj,
                            char *buf, size_t size);
int                      schema_dump_match_rule(struct match_rule *mr,
                            char *buf, size_t size);

struct attr_type        *lookup_attribute_by_oid(struct schema *schema, char *oid);
struct attr_type        *lookup_attribute_by_name(struct schema *schema, char *name);
struct attr_type        *lookup_attribute(struct schema *schema, char *oid_or_name);
struct object           *lookup_object_by_oid(struct schema *schema, char *oid);
struct object           *lookup_object_by_name(struct schema *schema, char *name);
struct object           *lookup_object(struct schema *schema, char *oid_or_name);
char                    *lookup_symbolic_oid(struct schema *schema, char *name);
int                      is_oidstr(const char *oidstr);

/* syntax.c */
const struct syntax     *syntax_lookup(const char *oid);

/* matching.c */
extern struct match_rule match_rules[];
extern int num_match_rules;
const struct match_rule *match_rule_lookup(const char *oid);

#endif