/* WARNING: This file was generated by dkct. Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: itaconf.ctr */ /* Copyright (C) 2012-2017, Dirk Krause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file itaconf.c The itaconf module. */ #line 10 "itaconf.ctr" #include "dk3all.h" #include "itadmin.h" #line 17 "itaconf.ctr" /** Key names in configuration file. */ static dkChar const * const itadmin_config_keys[] = { /* 0 */ dkT("database-host"), /* 1 */ dkT("database-name"), /* 2 */ dkT("database-credentials-file"), /* 3 */ dkT("dhcpd.conf-vlan"), /* 4 */ dkT("organization"), /* 5 */ dkT("organizational-unit"), /* 6 */ dkT("administrator-name"), /* 7 */ dkT("create-dhcpd.conf"), /* 8 */ dkT("database-type"), /* 9 */ dkT("ldap-base"), /* 10 */ dkT("use-koma-script"), /* 11 */ dkT("msft-release-lease-on-shutdown"), NULL #line 73 "itaconf.ctr" }; /** Items for "msft release lease on shutdown". */ static const char * const msft_release_keys[] = { "none", "pool", "all", NULL }; /** Names of SQL database types. */ static dkChar const * const itadmin_config_database_types[] = { /* 0 */ dkT("MySQL"), NULL #line 93 "itaconf.ctr" }; /** Keywords to watch out for when processing a credential file. Typically this is a .my.cnf file. */ static dkChar const * const itadmin_config_credential_keys[] = { /* 0 */ dkT("client"), /* 1 */ dkT("user"), /* 2 */ dkT("password"), NULL #line 115 "itaconf.ctr" }; /** Set one string entry in job structure. @param job Job structure to modify. @param resptr Pointer to result pointer. @param srcptr Source string. @return 1 on success, 0 on error. */ static int itadmin_config_set_string( itadmin_job *job, dkChar const **resptr, dkChar const *srcptr ) { dkChar const *np; /* New string duplicate. */ int back = 0; #line 136 "itaconf.ctr" np = dk3str_dup_app(srcptr,job->app); if(np) { dk3_release(*resptr); *resptr = np; back = 1; } else { /* ERROR: Memory allocation failed! */ } #line 144 "itaconf.ctr" return back; } /** Configure a boolean value setting. @param job Job structure. @param bp Pointer to result variable. @param defv Default value, used for empty or non-boolean strings. @param txt Configuration text. @return 1 on success, 0 on error. */ static int itadmin_config_set_bool(itadmin_job *job, int *bp, int defv, dkChar const *txt) { dkChar lb[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of value. */ dkChar *p1; /* Start of text in copy. */ int back = 1; #line 164 "itaconf.ctr" if(txt) { p1 = dk3str_start(txt, NULL); if(p1) { if(dk3str_len(p1) < DK3_SIZEOF(lb,dkChar)) { dk3str_cpy_not_overlapped(lb, p1); dk3str_normalize(lb,NULL,dkT(' ')); if(dk3str_is_bool(lb)) { *bp = ((dk3str_is_on(lb)) ? 1 : 0); } else { #line 173 "itaconf.ctr" back = 0; *bp = defv; /* ERROR: Not a boolean! */ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 106, 107, lb); } } else { #line 179 "itaconf.ctr" back = 0; *bp = defv; /* ERROR: Text too long! */ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 108, 109, p1); } } else { #line 185 "itaconf.ctr" *bp = defv; } } else { #line 188 "itaconf.ctr" *bp = defv; } #line 190 "itaconf.ctr" return back; } /** Set database type. @param job Job structure. @param txt Text for database type (at this time only "MySQL" can be used). @return 1 on success, 0 on error. */ static int itadmin_config_set_dbtype(itadmin_job *job, dkChar const *txt) { int back = 0; int i; /* Index of type in array of known types. */ if(txt) { i = dk3str_array_index(itadmin_config_database_types, txt, 0); if(i >= 0) { job->dbt = i; back = 1; } else { /* ERROR: No such database type! */ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 110, 111, txt); } } else { /* ERROR: Empty text. */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 112); } return back; } /** Handler function for one configuration file line. @param obj Reader object. @param il Input line to process (constant text). @return 1 for OK, 0 for recoverable error, -1 for abort. */ static int itadmin_config_const_line_handler(void *obj, dkChar const *il) { dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Private copy of line.*/ itadmin_job *job; dkChar *p1; /* Start of line. */ dkChar *p2; /* Start of value in line. */ int back = 0; #line 241 "itaconf.ctr" if((obj) && (il)) { job = (itadmin_job *)obj; if(dk3str_len(il) < DK3_SIZEOF(line,dkChar)) { dk3str_cpy_not_overlapped(line, il); dk3str_delnl(line); p1 = dk3str_start(line, NULL); if(p1) { if(*p1 == dkT('#')) { back = 1; /* Comment line. */ } else { p2 = dk3str_chr(p1, dkT('=')); if(p2) { *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL); if(p2) { dk3str_normalize(p1, NULL, dkT('-')); switch(dk3str_array_index(itadmin_config_keys, p1, 0)) { case 0: { /* database host */ back = itadmin_config_set_string(job, &(job->dbhn), p2); } break; case 1: { /* database name */ back = itadmin_config_set_string(job, &(job->dbn), p2); } break; case 2: { /* credentials file */ back = itadmin_config_set_string(job, &(job->dbcf), p2); } break; case 3: { /* VLAN name */ back = itadmin_config_set_string(job, &(job->vlan), p2); if(back) { job->f_dh = 1; } } break; case 4: { /* organization */ back = itadmin_config_set_string(job, &(job->org), p2); } break; case 5: { /* organizational unit */ back = itadmin_config_set_string(job, &(job->ou), p2); } break; case 6: { /* administrator name */ back = itadmin_config_set_string(job, &(job->admn), p2); } break; case 7: { back = itadmin_config_set_bool(job, &(job->f_dh), 1, p2); } break; case 8: { back = itadmin_config_set_dbtype(job, p2); } break; case 9: { dk3str_normalize(p2, NULL, ' '); back = itadmin_config_set_string(job, &(job->ldapb), p2); } break; case 10: { if(dk3str_is_bool(p2)) { back = 1; job->ukoma = ((dk3str_is_on(p2)) ? 1 : 0); } else { /* ERROR: Boolean expected! */ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,106,107,p2); } } break; case 11: { switch(dk3str_array_index(msft_release_keys, p2, 0)) { case 0: { job->rel = 0; back = 1; } break; case 1: { job->rel = 1; back = 1; } break; case 2: { job->rel = 2; back = 1; } break; default: { /* ##### ERROR: Illegal keyword */ } break; } } break; default: { /* ERROR: Unknown option ... */ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 113, 114, p1); } break; } } else { /* ERROR: No value! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 115); } } else { /* ERROR: Missing '=' */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 115); } } } else { back = 1; /* Empty line. */ } } else { /* ERROR: Input line too long! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 116); } } #line 339 "itaconf.ctr" return back; } /** Handler function for one configuration file line. @param obj Reader object. @param il Input line to process. @return 1 for OK, 0 for recoverable error, -1 for abort. */ static int itadmin_cred_file_const_line_handler(void *obj, dkChar const *il) { dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of line. */ dkChar *p1; /* Start of key. */ dkChar *p2; /* Start of value. */ itadmin_cred_reader *reader; /* Help structure to read creds. */ int back = 0; #line 359 "itaconf.ctr" if((obj) && (il)) { #line 360 "itaconf.ctr" reader = (itadmin_cred_reader *)obj; if(dk3str_len(il) < DK3_SIZEOF(line,dkChar)) { #line 362 "itaconf.ctr" dk3str_cpy_not_overlapped(line, il); dk3str_delnl(line); p1 = dk3str_start(line, NULL); if(p1) { #line 366 "itaconf.ctr" if(*p1 == dkT('#')) { #line 367 "itaconf.ctr" back = 1; /* Ignore comment. */ } else { #line 369 "itaconf.ctr" if(*p1 == dkT('[')) { #line 370 "itaconf.ctr" reader->f_clnt = 0; p1++; p2 = dk3str_chr(p1, dkT(']')); if(p2) { #line 374 "itaconf.ctr" back = 1; *p2 = dkT('\0'); if(dk3str_cmp(p1, itadmin_config_credential_keys[0]) == 0) { reader->f_clnt = 1; } } else { #line 380 "itaconf.ctr" /* ERROR: Syntax! */ dk3app_log_1( (reader->job)->app, DK3_LL_ERROR, (reader->job)->msg, 117 ); } } else { #line 386 "itaconf.ctr" back = 1; p2 = dk3str_chr(p1, dkT('=')); if(p2) { #line 389 "itaconf.ctr" *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL); if(p2) { #line 392 "itaconf.ctr" dk3str_normalize(p1,NULL,dkT(' ')); switch(dk3str_array_index(itadmin_config_credential_keys,p1,0)) { case 1: { /* user */ #line 396 "itaconf.ctr" back = itadmin_config_set_string( reader->job, &((reader->job)->dbus), p2 ); } break; case 2: { /* password */ #line 401 "itaconf.ctr" back = itadmin_config_set_string( reader->job, &((reader->job)->dbpw), p2 ); } break; } } else { #line 407 "itaconf.ctr" /* Empty key. */ } } else { #line 410 "itaconf.ctr" /* Not a key=value line. */ } } } } else { #line 415 "itaconf.ctr" back = 1; /* Ignore empty line. */ } } else { #line 418 "itaconf.ctr" /* ERROR: Line too long! */ dk3app_log_1( (reader->job)->app, DK3_LL_ERROR, (reader->job)->msg, 116 ); } } else { #line 424 "itaconf.ctr" } #line 425 "itaconf.ctr" return back; } /** Handler function for one configuration file line. @param obj Reader object. @param il Input line to process. @return 1 for OK, 0 for recoverable error, -1 for abort. */ static int itadmin_cred_file_line_handler(void *obj, dkChar *il) { int back; back = itadmin_cred_file_const_line_handler(obj, il); return back; } /** Handler function for one configuration file line. @param obj Reader object. @param il Input line to process. @return 1 for OK, 0 for recoverable error, -1 for abort. */ static int itadmin_config_line_handler(void *obj, dkChar *il) { int back; back = itadmin_config_const_line_handler(obj, il); return back; } /** Process one configuration file. @param job Job structure. @param fn File name to process. @return 1 on success, 0 on error. */ static int itadmin_config_process_one_file(itadmin_job *job, dkChar const *fn) { dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of line. */ int back = 0; #line 474 "itaconf.ctr" back = dk3stream_process_filename_lines_app( (void *)job, itadmin_config_line_handler, fn, line, DK3_SIZEOF(line,dkChar), dk3app_get_encoding(job->app), dk3app_get_input_file_encoding(job->app), job->app ); if(back < 1) { back = 0; } #line 487 "itaconf.ctr" return back; } /** Read credentials file to obtain database user name and password. @param job Job structure. @return 1 on success, 0 on error. */ static int itadmin_config_read_credentials(itadmin_job *job) { dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */ dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Input line buffer. */ itadmin_cred_reader reader; /* Helper structure to read creds. */ int back = 0; #line 505 "itaconf.ctr" if(dk3str_len(job->dbcf) < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy_not_overlapped(fnb, job->dbcf); dk3str_correct_filename(fnb); if(dk3sf_must_expand(fnb)) { /* ERROR: File name must not contain wildcards! */ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 118, 119, fnb); } else { if(!dk3str_is_abs_path(fnb)) { /* WARNING: File name should be specified as absolute path! */ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 120, 121, fnb); } reader.job = job; reader.f_clnt = 1; #line 518 "itaconf.ctr" back = dk3stream_process_filename_sanitized_lines_app( (void *)(&reader), itadmin_cred_file_line_handler, fnb, line, DK3_SIZEOF(line,dkChar), dk3app_get_encoding(job->app), dk3app_get_input_file_encoding(job->app), job->app ); } } else { /* ERROR: File name too long! */ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, job->dbcf); } if(job->ec) { #line 534 "itaconf.ctr" back = 0; } #line 536 "itaconf.ctr" return back; } int itadmin_config_read(itadmin_job *job) { dkChar fnb[DK3_MAX_PATH]; /* Copy of file name. */ dk3_search_t *res; /* Search result, config. */ dk3_dir_t *fne; /* File name expander. */ dk3_stat_t const *es; /* Expandend file status. */ dkChar const *fn; /* File name. */ dkChar const *en; /* Expanded file name. */ dkChar const *fnorig; /* Original file name. */ int back = 0; int have_file = 0; /* Flag: File found. */ int have_error = 0; /* Flag: Error occured. */ int argc; /* Number of file names. */ int i; /* Current file name index. */ #line 557 "itaconf.ctr" /* Process default configuration files. */ res = dk3app_find_config_file(job->app, (job->noloc)[4], 0); if(res) { dk3search_reset(res); while((fn = dk3search_next(res)) != NULL) { have_file = 1; if(!itadmin_config_process_one_file(job, fn)) { have_error = 1; } } dk3search_close(res); } /* Process configuration file(s) specified on command line. */ argc = dk3opt_get_num_args(job->opt); for(i = 0; i < argc; i++) { fnorig = dk3opt_get_arg(job->opt, i); if(fnorig) { if(dk3str_len(fnorig) < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy_not_overlapped(fnb, fnorig); dk3str_correct_filename(fnb); if(dk3sf_must_expand(fnb)) { fne = dk3dir_fne_open_app(fnb, job->app); if(fne) { while(dk3dir_get_next_file(fne)) { en = dk3dir_get_fullname(fne); es = dk3dir_get_stat(fne); if((en) && (es)) { switch((es->ft) & (~(DK3_FT_SYMLINK))) { case DK3_FT_REGULAR: { have_file = 1; if(!itadmin_config_process_one_file(job, fnb)) { have_error = 1; } } break; default: { have_error = 1; /* ERROR: Wrong file type! */ dk3app_log_i3(job->app, DK3_LL_ERROR, 255, 256, en); } break; } } else { /* BUG: No complete information available! */ } } dk3dir_close(fne); } else { /* ERROR: Failed to expand file name! */ } } else { have_file = 1; if(!itadmin_config_process_one_file(job, fnb)) { have_error = 1; } } } else { /* ERROR: File name fnorig too long! */ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, fnorig); } } else { /* BUG: No pointer returned! */ } } /* Final tests and error messages. */ if(have_file) { #line 627 "itaconf.ctr" if(!(have_error)) { #line 628 "itaconf.ctr" back = 1; if(!(job->dbhn)) { #line 630 "itaconf.ctr" /* ERROR: Missing database host name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 122); back = 0; } if(!(job->dbn)) { #line 635 "itaconf.ctr" /* ERROR: Missing database name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 123); back = 0; } if(!(job->vlan)) { #line 640 "itaconf.ctr" /* Warning: Missing VLAN name! */ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 124); } if(!(job->org)) { #line 644 "itaconf.ctr" /* ERROR: Missing organization name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 125); back = 0; } if(!(job->ou)) { #line 649 "itaconf.ctr" /* ERROR: Missing organizational unit name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 126); back = 0; } if(!(job->admn)) { #line 654 "itaconf.ctr" /* ERROR: Missing administrator name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 127); back = 0; } if(!(job->dbcf)) { #line 659 "itaconf.ctr" /* ERROR: Missing database credentials file name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 128); back = 0; } else { #line 663 "itaconf.ctr" if(back) { #line 664 "itaconf.ctr" back = itadmin_config_read_credentials(job); if(back) { if(!(job->dbus)) { #line 667 "itaconf.ctr" /* ERROR: Missing database user name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 129); back = 0; } if(!(job->dbpw)) { #line 672 "itaconf.ctr" /* ERROR: Missing database user password! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 130); back = 0; } } } } if(back) { if(!(job->ukoma)) { if(dk3str_casecmp(dkT("de"), dk3app_get_language(job->app)) == 0) { dk3app_log_1(job->app, DK3_LL_INFO, job->msg, 302); } } } if(!(back)) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 132); } } else { #line 690 "itaconf.ctr" } } else { #line 692 "itaconf.ctr" /* ERROR: No configuration file found for processing! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 131); } #line 695 "itaconf.ctr" return back; }