diff options
author | Martin Hedenfal <martinh@cvs.openbsd.org> | 2010-07-02 05:23:41 +0000 |
---|---|---|
committer | Martin Hedenfal <martinh@cvs.openbsd.org> | 2010-07-02 05:23:41 +0000 |
commit | feee5618724608016262d9d30337d44e8defc5f3 (patch) | |
tree | 9b91b7714389c1b10dbef1a902a264cafe713aa4 /usr.sbin/ldapd/schema.c | |
parent | e096f67c64cdf963cf9b5a033b0065be2f5c2f68 (diff) |
Dump parsed schema to buffer and send in requests for the cn=schema
subschema namespace. Only do this if 'objectClasses' and 'attributeTypes'
are expicitly requested. This allows clients to for example present custom
editing forms.
Diffstat (limited to 'usr.sbin/ldapd/schema.c')
-rw-r--r-- | usr.sbin/ldapd/schema.c | 239 |
1 files changed, 238 insertions, 1 deletions
diff --git a/usr.sbin/ldapd/schema.c b/usr.sbin/ldapd/schema.c index 0bfeb38f554..f8ce78d898a 100644 --- a/usr.sbin/ldapd/schema.c +++ b/usr.sbin/ldapd/schema.c @@ -1,4 +1,4 @@ -/* $OpenBSD: schema.c,v 1.7 2010/07/02 00:42:50 martinh Exp $ */ +/* $OpenBSD: schema.c,v 1.8 2010/07/02 05:23:40 martinh Exp $ */ /* * Copyright (c) 2010 Martin Hedenfalk <martinh@openbsd.org> @@ -681,6 +681,7 @@ schema_parse_attributetype(struct schema *schema) log_warn("calloc"); goto fail; } + attr->usage = USAGE_USER_APP; if (is_oidstr(kw)) attr->oid = kw; @@ -999,3 +1000,239 @@ schema_parse(struct schema *schema, const char *filename) return ret; } +static int +schema_dump_names(const char *desc, struct name_list *nlist, + char *buf, size_t size) +{ + struct name *name; + + if (nlist == NULL || SLIST_EMPTY(nlist)) + return 0; + + if (strlcat(buf, " ", size) >= size || + strlcat(buf, desc, size) >= size) + return -1; + + name = SLIST_FIRST(nlist); + if (SLIST_NEXT(name, next) == NULL) { + /* single name, no parenthesis */ + if (strlcat(buf, " '", size) >= size || + strlcat(buf, name->name, size) >= size || + strlcat(buf, "'", size) >= size) + return -1; + } else { + if (strlcat(buf, " ( ", size) >= size) + return -1; + SLIST_FOREACH(name, nlist, next) + if (strlcat(buf, "'", size) >= size || + strlcat(buf, name->name, size) >= size || + strlcat(buf, "' ", size) >= size) + return -1; + if (strlcat(buf, ")", size) >= size) + return -1; + } + + return 0; +} + +static int +schema_dump_attrlist(const char *desc, struct attr_list *alist, + char *buf, size_t size) +{ + struct attr_ptr *aptr; + + if (alist == NULL || SLIST_EMPTY(alist)) + return 0; + + if (strlcat(buf, " ", size) >= size || + strlcat(buf, desc, size) >= size) + return -1; + + aptr = SLIST_FIRST(alist); + if (SLIST_NEXT(aptr, next) == NULL) { + /* single attribute, no parenthesis */ + if (strlcat(buf, " ", size) >= size || + strlcat(buf, ATTR_NAME(aptr->attr_type), size) >= size) + return -1; + } else { + if (strlcat(buf, " ( ", size) >= size) + return -1; + SLIST_FOREACH(aptr, alist, next) { + if (strlcat(buf, ATTR_NAME(aptr->attr_type), + size) >= size || + strlcat(buf, " ", size) >= size) + return -1; + if (SLIST_NEXT(aptr, next) != NULL && + strlcat(buf, "$ ", size) >= size) + return -1; + } + if (strlcat(buf, ")", size) >= size) + return -1; + } + + return 0; +} + +static int +schema_dump_objlist(const char *desc, struct obj_list *olist, + char *buf, size_t size) +{ + struct obj_ptr *optr; + + if (olist == NULL || SLIST_EMPTY(olist)) + return 0; + + if (strlcat(buf, " ", size) >= size || + strlcat(buf, desc, size) >= size) + return -1; + + optr = SLIST_FIRST(olist); + if (SLIST_NEXT(optr, next) == NULL) { + /* single attribute, no parenthesis */ + if (strlcat(buf, " ", size) >= size || + strlcat(buf, OBJ_NAME(optr->object), size) >= size) + return -1; + } else { + if (strlcat(buf, " ( ", size) >= size) + return -1; + SLIST_FOREACH(optr, olist, next) { + if (strlcat(buf, OBJ_NAME(optr->object), size) >= size || + strlcat(buf, " ", size) >= size) + return -1; + if (SLIST_NEXT(optr, next) != NULL && + strlcat(buf, "$ ", size) >= size) + return -1; + } + if (strlcat(buf, ")", size) >= size) + return -1; + } + + return 0; +} + +int +schema_dump_object(struct object *obj, char *buf, size_t size) +{ + if (strlcpy(buf, "( ", size) >= size || + strlcat(buf, obj->oid, size) >= size) + return -1; + + if (schema_dump_names("NAME", obj->names, buf, size) != 0) + return -1; + + if (obj->desc != NULL) + if (strlcat(buf, " DESC '", size) >= size || + strlcat(buf, obj->desc, size) >= size || + strlcat(buf, "'", size) >= size) + return -1; + + switch (obj->kind) { + case KIND_STRUCTURAL: + if (strlcat(buf, " STRUCTURAL", size) >= size) + return -1; + break; + case KIND_ABSTRACT: + if (strlcat(buf, " ABSTRACT", size) >= size) + return -1; + break; + case KIND_AUXILIARY: + if (strlcat(buf, " AUXILIARY", size) >= size) + return -1; + break; + } + + if (schema_dump_objlist("SUP", obj->sup, buf, size) != 0) + return -1; + + if (obj->obsolete && strlcat(buf, " OBSOLETE", size) >= size) + return -1; + + if (schema_dump_attrlist("MUST", obj->must, buf, size) != 0) + return -1; + + if (schema_dump_attrlist("MAY", obj->may, buf, size) != 0) + return -1; + + if (strlcat(buf, " )", size) >= size) + return -1; + + return 0; +} + +int +schema_dump_attribute(struct attr_type *at, char *buf, size_t size) +{ + if (strlcpy(buf, "( ", size) >= size || + strlcat(buf, at->oid, size) >= size) + return -1; + + if (schema_dump_names("NAME", at->names, buf, size) != 0) + return -1; + + if (at->desc != NULL) + if (strlcat(buf, " DESC ", size) >= size || + strlcat(buf, at->desc, size) >= size || + strlcat(buf, "'", size) >= size) + return -1; + + if (at->obsolete && strlcat(buf, " OBSOLETE", size) >= size) + return -1; + + if (at->sup != NULL) + if (strlcat(buf, " SUP ", size) >= size || + strlcat(buf, ATTR_NAME(at->sup), size) >= size) + return -1; + + if (at->equality != NULL) + if (strlcat(buf, " EQUALITY ", size) >= size || + strlcat(buf, at->equality, size) >= size) + return -1; + + if (at->ordering != NULL) + if (strlcat(buf, " ORDERING ", size) >= size || + strlcat(buf, at->ordering, size) >= size) + return -1; + + if (at->substr != NULL) + if (strlcat(buf, " SUBSTR ", size) >= size || + strlcat(buf, at->substr, size) >= size) + return -1; + + if (at->syntax != NULL) + if (strlcat(buf, " SYNTAX ", size) >= size || + strlcat(buf, at->syntax, size) >= size) + return -1; + + if (at->single && strlcat(buf, " SINGLE-VALUE", size) >= size) + return -1; + + if (at->collective && strlcat(buf, " COLLECTIVE", size) >= size) + return -1; + + if (at->immutable && strlcat(buf, " NO-USER-MODIFICATION", size) >= size) + return -1; + + switch (at->usage) { + case USAGE_USER_APP: + /* User application usage is the default. */ + break; + case USAGE_DIR_OP: + if (strlcat(buf, " USAGE directoryOperation", size) >= size) + return -1; + break; + case USAGE_DIST_OP: + if (strlcat(buf, " USAGE distributedOperation", size) >= size) + return -1; + break; + case USAGE_DSA_OP: + if (strlcat(buf, " USAGE dSAOperation", size) >= size) + return -1; + break; + } + + if (strlcat(buf, " )", size) >= size) + return -1; + + return 0; +} + |