1 /* 2 * Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org> 3 * Copyright (c) 2006, 2007 Marc Balmer <mbalmer@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <stdio.h> 19 #include "ber.h" 20 21 #define LDAP_URL "ldap://" 22 #define LDAP_PORT 389 23 #define LDAP_PAGED_OID "1.2.840.113556.1.4.319" 24 25 struct aldap { 26 #define ALDAP_ERR_SUCCESS 0 27 #define ALDAP_ERR_PARSER_ERROR 1 28 #define ALDAP_ERR_INVALID_FILTER 2 29 #define ALDAP_ERR_OPERATION_FAILED 3 30 uint8_t err; 31 int msgid; 32 struct ber ber; 33 }; 34 35 struct aldap_page_control { 36 int size; 37 char *cookie; 38 unsigned int cookie_len; 39 }; 40 41 struct aldap_message { 42 int msgid; 43 int message_type; 44 45 struct ber_element *msg; 46 47 struct ber_element *header; 48 struct ber_element *protocol_op; 49 50 struct ber_element *dn; 51 52 union { 53 struct { 54 long long rescode; 55 struct ber_element *diagmsg; 56 } res; 57 struct { 58 struct ber_element *iter; 59 struct ber_element *attrs; 60 } search; 61 } body; 62 struct ber_element *references; 63 struct aldap_page_control *page; 64 }; 65 66 enum aldap_protocol { 67 LDAP, 68 LDAPS 69 }; 70 71 struct aldap_url { 72 int protocol; 73 char *host; 74 in_port_t port; 75 char *dn; 76 #define MAXATTR 1024 77 char *attributes[MAXATTR]; 78 int scope; 79 char *filter; 80 char *buffer; 81 }; 82 83 enum protocol_op { 84 LDAP_REQ_BIND = 0, 85 LDAP_RES_BIND = 1, 86 LDAP_REQ_UNBIND_30 = 2, 87 LDAP_REQ_SEARCH = 3, 88 LDAP_RES_SEARCH_ENTRY = 4, 89 LDAP_RES_SEARCH_RESULT = 5, 90 LDAP_REQ_MODIFY = 6, 91 LDAP_RES_MODIFY = 7, 92 LDAP_REQ_ADD = 8, 93 LDAP_RES_ADD = 9, 94 LDAP_REQ_DELETE_30 = 10, 95 LDAP_RES_DELETE = 11, 96 LDAP_REQ_MODRDN = 12, 97 LDAP_RES_MODRDN = 13, 98 LDAP_REQ_COMPARE = 14, 99 LDAP_RES_COMPARE = 15, 100 LDAP_REQ_ABANDON_30 = 16, 101 102 LDAP_RES_SEARCH_REFERENCE = 19, 103 }; 104 105 enum deref_aliases { 106 LDAP_DEREF_NEVER = 0, 107 LDAP_DEREF_SEARCHING = 1, 108 LDAP_DEREF_FINDING = 2, 109 LDAP_DEREF_ALWAYS = 3, 110 }; 111 112 enum authentication_choice { 113 LDAP_AUTH_SIMPLE = 0, 114 }; 115 116 enum scope { 117 LDAP_SCOPE_BASE = 0, 118 LDAP_SCOPE_ONELEVEL = 1, 119 LDAP_SCOPE_SUBTREE = 2, 120 }; 121 122 enum result_code { 123 LDAP_SUCCESS = 0, 124 LDAP_OPERATIONS_ERROR = 1, 125 LDAP_PROTOCOL_ERROR = 2, 126 LDAP_TIMELIMIT_EXCEEDED = 3, 127 LDAP_SIZELIMIT_EXCEEDED = 4, 128 LDAP_COMPARE_FALSE = 5, 129 LDAP_COMPARE_TRUE = 6, 130 LDAP_STRONG_AUTH_NOT_SUPPORTED = 7, 131 LDAP_STRONG_AUTH_REQUIRED = 8, 132 133 LDAP_REFERRAL = 10, 134 LDAP_ADMINLIMIT_EXCEEDED = 11, 135 LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12, 136 LDAP_CONFIDENTIALITY_REQUIRED = 13, 137 LDAP_SASL_BIND_IN_PROGRESS = 14, 138 LDAP_NO_SUCH_ATTRIBUTE = 16, 139 LDAP_UNDEFINED_TYPE = 17, 140 LDAP_INAPPROPRIATE_MATCHING = 18, 141 LDAP_CONSTRAINT_VIOLATION = 19, 142 LDAP_TYPE_OR_VALUE_EXISTS = 20, 143 LDAP_INVALID_SYNTAX = 21, 144 145 LDAP_NO_SUCH_OBJECT = 32, 146 LDAP_ALIAS_PROBLEM = 33, 147 LDAP_INVALID_DN_SYNTAX = 34, 148 149 LDAP_ALIAS_DEREF_PROBLEM = 36, 150 151 LDAP_INAPPROPRIATE_AUTH = 48, 152 LDAP_INVALID_CREDENTIALS = 49, 153 LDAP_INSUFFICIENT_ACCESS = 50, 154 LDAP_BUSY = 51, 155 LDAP_UNAVAILABLE = 52, 156 LDAP_UNWILLING_TO_PERFORM = 53, 157 LDAP_LOOP_DETECT = 54, 158 159 LDAP_NAMING_VIOLATION = 64, 160 LDAP_OBJECT_CLASS_VIOLATION = 65, 161 LDAP_NOT_ALLOWED_ON_NONLEAF = 66, 162 LDAP_NOT_ALLOWED_ON_RDN = 67, 163 LDAP_ALREADY_EXISTS = 68, 164 LDAP_NO_OBJECT_CLASS_MODS = 69, 165 166 LDAP_AFFECTS_MULTIPLE_DSAS = 71, 167 168 LDAP_OTHER = 80, 169 }; 170 171 enum ldap_filter { 172 LDAP_FILT_AND = 0, 173 LDAP_FILT_OR = 1, 174 LDAP_FILT_NOT = 2, 175 LDAP_FILT_EQ = 3, 176 LDAP_FILT_SUBS = 4, 177 LDAP_FILT_GE = 5, 178 LDAP_FILT_LE = 6, 179 LDAP_FILT_PRES = 7, 180 LDAP_FILT_APPR = 8, 181 }; 182 183 enum ldap_subfilter { 184 LDAP_FILT_SUBS_INIT = 0, 185 LDAP_FILT_SUBS_ANY = 1, 186 LDAP_FILT_SUBS_FIN = 2, 187 }; 188 189 struct aldap *aldap_init(int fd); 190 int aldap_close(struct aldap *); 191 struct aldap_message *aldap_parse(struct aldap *); 192 void aldap_freemsg(struct aldap_message *); 193 194 int aldap_bind(struct aldap *, char *, char *); 195 int aldap_unbind(struct aldap *); 196 int aldap_search(struct aldap *, char *, enum scope, char *, char **, int, int, int, struct aldap_page_control *); 197 int aldap_get_errno(struct aldap *, const char **); 198 199 int aldap_get_resultcode(struct aldap_message *); 200 char *aldap_get_dn(struct aldap_message *); 201 char *aldap_get_diagmsg(struct aldap_message *); 202 char **aldap_get_references(struct aldap_message *); 203 void aldap_free_references(char **values); 204 int aldap_parse_url(char *, struct aldap_url *); 205 void aldap_free_url(struct aldap_url *); 206 #if 0 207 int aldap_search_url(struct aldap *, char *, int, int, int); 208 #endif 209 210 int aldap_count_attrs(struct aldap_message *); 211 int aldap_match_attr(struct aldap_message *, char *, char ***); 212 int aldap_first_attr(struct aldap_message *, char **, char ***); 213 int aldap_next_attr(struct aldap_message *, char **, char ***); 214 int aldap_free_attr(char **); 215 216 struct aldap_page_control *aldap_parse_page_control(struct ber_element *, size_t len); 217 void aldap_freepage(struct aldap_page_control *); 218