1 /* -*- show-trailing-whitespace: t; indent-tabs: t -*- 2 * 3 * Copyright (c) 2003,2004,2005,2006 David Lichteblau 4 * Copyright (c) 2006 Perry Nguyen 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 #include <dirent.h> 21 #include <errno.h> 22 #include <fcntl.h> 23 #include <glib.h> 24 /* fixme: */ 25 #define LDAP_DEPRECATED 1 26 #include <ldap.h> 27 #include <ldap_schema.h> 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <strings.h> 32 #include <sys/ioctl.h> 33 #include <sys/stat.h> 34 #if !defined(__DragonFly__) && !defined(__FreeBSD__) 35 #include <sys/termios.h> 36 #else 37 #include <termios.h> 38 #endif 39 #include <sys/time.h> 40 #include <sys/types.h> 41 #include <sys/wait.h> 42 #include <time.h> 43 #include <unistd.h> 44 #include <ctype.h> 45 46 #define MANUAL_SYNTAX_URL "http://www.lichteblau.com/ldapvi/manual#syntax" 47 #define MANUAL_LDIF_URL "http://www.lichteblau.com/ldapvi/manual#syntax-ldif" 48 #define RFC_2849_URL "http://www.rfc-editor.org/rfc/rfc2849.txt" 49 50 typedef struct tschema { 51 GHashTable *classes; 52 GHashTable *types; 53 } tschema; 54 55 typedef struct tentroid { 56 tschema *schema; 57 GPtrArray *classes; 58 GPtrArray *must; 59 GPtrArray *may; 60 LDAPObjectClass *structural; 61 GString *comment; 62 GString *error; 63 } tentroid; 64 65 66 67 /* 68 * error.c 69 */ 70 #define syserr() do_syserr(__FILE__, __LINE__) 71 72 void do_syserr(char *file, int line); 73 void yourfault(char *str); 74 void ldaperr(LDAP *ld, char *str); 75 76 /* 77 * arguments.c 78 */ 79 enum ldapvi_mode { 80 ldapvi_mode_edit, ldapvi_mode_in, ldapvi_mode_out, 81 ldapvi_mode_delete, ldapvi_mode_rename, ldapvi_mode_modrdn 82 }; 83 84 enum bind_dialog { 85 BD_NEVER = LDAP_SASL_QUIET, 86 BD_AUTO = LDAP_SASL_AUTOMATIC, 87 BD_ALWAYS = LDAP_SASL_INTERACTIVE 88 }; 89 90 /* FIXME (?): For now, we recklessly leak all strings stored in 91 * bind_options when reauthentication is performed and new values are 92 * stored. */ 93 typedef struct bind_options { 94 ber_tag_t authmethod; /* LDAP_AUTH_SASL or LDAP_AUTH_NONE */ 95 enum bind_dialog dialog; 96 char *user; /* DN or user search filter */ 97 char *password; /* Simple or SASL passwd */ 98 char *sasl_authcid; 99 char *sasl_authzid; 100 char *sasl_mech; 101 char *sasl_realm; 102 char *sasl_secprops; 103 } bind_options; 104 105 typedef struct cmdline { 106 char *server; 107 GPtrArray *basedns; 108 int scope; 109 char *filter; 110 char **attrs; 111 bind_options bind_options; 112 int quiet; 113 int referrals; 114 GPtrArray *classes; 115 int ldapmodify_add; 116 int managedsait; 117 char *sortkeys; 118 int starttls; 119 int tls; 120 int deref; 121 int verbose; 122 int noquestions; 123 int noninteractive; 124 int discover; 125 int config; 126 int ldif; 127 int ldapvi; 128 int mode; 129 char **delete_dns; 130 char *rename_old; 131 char *rename_new; 132 int rename_dor; 133 char *in_file; 134 int schema_comments; 135 int continuous; 136 int profileonlyp; 137 } cmdline; 138 139 void init_cmdline(cmdline *cmdline); 140 void parse_arguments( 141 int argc, const char **argv, cmdline *result, GPtrArray *ctrls); 142 void usage(int fd, int rc); 143 144 /* 145 * data.c 146 */ 147 typedef struct named_array { 148 char *name; 149 GPtrArray *array; 150 } named_array; 151 152 typedef struct tentry { 153 struct named_array e; 154 } tentry; 155 #define entry_dn(entry) ((entry)->e.name) 156 #define entry_attributes(entry) ((entry)->e.array) 157 158 typedef struct tattribute { 159 struct named_array a; 160 } tattribute; 161 #define attribute_ad(attribute) ((attribute)->a.name) 162 #define attribute_values(attribute) ((attribute)->a.array) 163 164 tentry *entry_new(char *dn); 165 void entry_free(tentry *e); 166 int entry_cmp(tentry *e, tentry *f); 167 168 tattribute *attribute_new(char *ad); 169 void attribute_free(tattribute *a); 170 int attribute_cmp(tattribute *a, tattribute *b); 171 172 int named_array_ptr_cmp(const void *aa, const void *bb); 173 174 LDAPMod *attribute2mods(tattribute *attribute); 175 LDAPMod **entry2mods(tentry *entry); 176 tattribute *entry_find_attribute(tentry *entry, char *ad, int createp); 177 void attribute_append_value(tattribute *attribute, char *data, int n); 178 int attribute_find_value(tattribute *attribute, char *data, int n); 179 int attribute_remove_value(tattribute *a, char *data, int n); 180 181 struct berval *string2berval(GArray *s); 182 struct berval *gstring2berval(GString *s); 183 char *array2string(GArray *av); 184 void xfree_berval(struct berval *bv); 185 186 /* 187 * parse.c 188 */ 189 typedef int (*parser_entry)(FILE *, long, char **, tentry **, long *); 190 typedef int (*parser_peek)(FILE *, long, char **, long *); 191 typedef int (*parser_skip)(FILE *, long, char **); 192 typedef int (*parser_rename)(FILE *, long, char **, char **, int *); 193 typedef int (*parser_delete)(FILE *, long, char **); 194 typedef int (*parser_modify)(FILE *, long, char **, LDAPMod ***); 195 typedef void (*print_entry)(FILE *, tentry *, char *, tentroid *); 196 197 typedef struct tparser { 198 parser_entry entry; 199 200 parser_peek peek; 201 parser_skip skip; 202 203 parser_rename rename; 204 parser_delete delete; 205 parser_modify modify; 206 207 print_entry print; /* ja, das muss so sein */ 208 } tparser; 209 210 extern tparser ldif_parser; 211 extern tparser ldapvi_parser; 212 213 int peek_entry(FILE *s, long offset, char **key, long *pos); 214 int read_entry(FILE *s, long offset, char **key, tentry **entry, long *pos); 215 int read_rename(FILE *s, long offset, char **dn1, char **dn2, int *); 216 int read_modify(FILE *s, long offset, char **dn, LDAPMod ***mods); 217 int read_delete(FILE *s, long offset, char **dn); 218 int skip_entry(FILE *s, long offset, char **key); 219 int read_profile(FILE *s, tentry **entry); 220 221 /* 222 * diff.c 223 */ 224 typedef int (*handler_change)(int, char *, char *, LDAPMod **, void *); 225 typedef int (*handler_rename)(int, char *, tentry *, void *); 226 typedef int (*handler_add)(int, char *, LDAPMod **, void *); 227 typedef int (*handler_delete)(int, char *, void *); 228 typedef int (*handler_rename0)(int, char *, char *, int, void *); 229 230 typedef struct thandler { 231 handler_change change; 232 handler_rename rename; 233 handler_add add; 234 handler_delete delete; 235 handler_rename0 rename0; 236 } thandler; 237 238 int compare_streams( 239 tparser *parser, 240 thandler *handler, 241 void *userdata, 242 GArray *offsets, 243 FILE *clean, 244 FILE *data, 245 long *error_position, 246 long *syntax_error_position); 247 248 enum frob_rdn_mode { 249 FROB_RDN_CHECK, FROB_RDN_REMOVE, FROB_RDN_ADD, FROB_RDN_CHECK_NONE 250 }; 251 int frob_rdn(tentry *entry, char *dn, int mode); 252 int process_immediate(tparser *, thandler *, void *, FILE *, long, char *); 253 254 255 /* 256 * misc.c 257 */ 258 enum dialog_mode { 259 DIALOG_DEFAULT, DIALOG_PASSWORD, DIALOG_CHALLENGE 260 }; 261 typedef struct dialog { 262 enum dialog_mode mode; 263 char *prompt; 264 char *value; 265 } tdialog; 266 267 int carray_cmp(GArray *a, GArray *b); 268 int carray_ptr_cmp(const void *aa, const void *bb); 269 void cp(char *src, char *dst, off_t skip, int append); 270 void fcopy(FILE *src, FILE *dst); 271 char choose(char *prompt, char *charbag, char *help); 272 void edit_pos(char *pathname, long pos); 273 void edit(char *pathname, long line); 274 void view(char *pathname); 275 int pipeview(int *fd); 276 void pipeview_wait(int pid); 277 char *home_filename(char *name); 278 void read_ldapvi_history(void); 279 void write_ldapvi_history(void); 280 char *ldapvi_getline(char *prompt, char *value); 281 char *get_password(); 282 char *append(char *a, char *b); 283 void *xalloc(size_t size); 284 char *xdup(char *str); 285 int adjoin_str(GPtrArray *, char *); 286 int adjoin_ptr(GPtrArray *, void *); 287 void init_dialog(tdialog *, enum dialog_mode, char *, char *); 288 void dialog(char *header, tdialog *, int, int); 289 290 /* 291 * schema.c 292 */ 293 char *objectclass_name(LDAPObjectClass *); 294 char *attributetype_name(LDAPAttributeType *); 295 296 tschema *schema_new(LDAP *ld); 297 void schema_free(tschema *schema); 298 LDAPObjectClass *schema_get_objectclass(tschema *, char *); 299 LDAPAttributeType *schema_get_attributetype(tschema *, char *); 300 301 tentroid *entroid_new(tschema *); 302 void entroid_reset(tentroid *); 303 void entroid_free(tentroid *); 304 LDAPObjectClass *entroid_get_objectclass(tentroid *, char *); 305 LDAPAttributeType *entroid_get_attributetype(tentroid *, char *); 306 LDAPObjectClass *entroid_request_class(tentroid *, char *); 307 int entroid_remove_ad(tentroid *, char *); 308 int compute_entroid(tentroid *); 309 310 /* 311 * print.c 312 */ 313 typedef enum t_print_binary_mode { 314 PRINT_ASCII, PRINT_UTF8, PRINT_JUNK 315 } t_print_binary_mode; 316 extern t_print_binary_mode print_binary_mode; 317 318 void print_ldapvi_entry(FILE *s, tentry *entry, char *key, tentroid *); 319 void print_ldapvi_modify(FILE *s, char *dn, LDAPMod **mods); 320 void print_ldapvi_rename(FILE *s, char *olddn, char *newdn, int deleteoldrdn); 321 void print_ldapvi_add(FILE *s, char *dn, LDAPMod **mods); 322 void print_ldapvi_delete(FILE *s, char *dn); 323 void print_ldapvi_modrdn(FILE *s, char *olddn, char *newrdn, int deleteoldrdn); 324 void print_ldapvi_message(FILE *, LDAP *, LDAPMessage *, int key, tentroid *); 325 void print_ldif_entry(FILE *s, tentry *entry, char *key, tentroid *); 326 void print_ldif_modify(FILE *s, char *dn, LDAPMod **mods); 327 void print_ldif_rename(FILE *s, char *olddn, char *newdn, int deleteoldrdn); 328 void print_ldif_add(FILE *s, char *dn, LDAPMod **mods); 329 void print_ldif_delete(FILE *s, char *dn); 330 void print_ldif_modrdn(FILE *s, char *olddn, char *newrdn, int deleteoldrdn); 331 void print_ldif_message(FILE *, LDAP *, LDAPMessage *, int key, tentroid *); 332 333 /* 334 * search.c 335 */ 336 void discover_naming_contexts(LDAP *ld, GPtrArray *basedns); 337 GArray *search( 338 FILE *s, LDAP *ld, cmdline *cmdline, LDAPControl **ctrls, int notty, 339 int ldif); 340 LDAPMessage *get_entry(LDAP *ld, char *dn, LDAPMessage **result); 341 342 /* 343 * port.c 344 */ 345 typedef void (*on_exit_function)(int, void *); 346 int g_string_append_sha(GString *string, char *key); 347 int g_string_append_ssha(GString *string, char *key); 348 int g_string_append_md5(GString *string, char *key); 349 int g_string_append_smd5(GString *string, char *key); 350 351 /* 352 * base64.c 353 */ 354 void print_base64(unsigned char const *src, size_t srclength, FILE *s); 355 void g_string_append_base64( 356 GString *string, unsigned char const *src, size_t srclength); 357 int read_base64(char const *src, unsigned char *target, size_t targsize); 358 359 /* 360 * sasl.c 361 */ 362 typedef struct sasl_defaults { 363 bind_options *bind_options; 364 GPtrArray *scratch; 365 char *pathname; 366 int fd, out, err; 367 } tsasl_defaults; 368 369 void init_sasl_redirection(tsasl_defaults *, char *); 370 void enable_sasl_redirection(tsasl_defaults *); 371 void disable_sasl_redirection(tsasl_defaults *); 372 void finish_sasl_redirection(tsasl_defaults *); 373 374 tsasl_defaults *sasl_defaults_new(bind_options *bind_options); 375 void sasl_defaults_free(tsasl_defaults *sd); 376 int ldapvi_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *p); 377