/*************************************************************************/ /* LDAPCONF - Linuxconf module for LDAP operation. Copyright (C) 1999,2000,2001 Stein Vråle This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details. **************************************************************************/ /* LDAPDB This object provide methods to manage LDAP database files and directory config. **************************************************************************/ #pragma implementation #include #include #include #include "ldapconf_defs.h" PUBLIC LDAPDB::LDAPDB () { } PUBLIC LDAPDB::LDAPDB (const char *dbname) { name.setfrom (dbname); } /*! Init database profile object */ PUBLIC int LDAPDB::init(const char *dbname) { int ret = 0; // Get fqdn and convert it to internet style suffix char buf[256]; gethostname(buf,sizeof(buf)); dns2dc(buf,sizeof(buf),1); // Set initial config bind.base.setfrom(buf); bind.dn.setfromf ("cn=manager,%s",buf); bind.pw.setfrom ("secret"); database.setfrom ("ldbm"); directory.setfromf ("%s/%s",OPENLDAP_DATA_DIR,dbname); replogfile.setfromf ("%s/%s/%s.log",OPENLDAP_DATA_DIR,dbname,dbname); updatedn.setfrom (""); replica.setfrom (""); lastmod.setfrom ("off"); readonly.setfrom ("off"); schemacheck.setfrom("on"); defaultaccess.setfrom("none"); loglevel.setfrom("0"); // Create directory file_mkdirp(directory.get(), mode_slapd_user.get(), mode_slapd_group.get(), 0700); return ret; } /*! Read database configuration from file */ PUBLIC int LDAPDB::read(const char *dbname) { int ret = 0; VIEWITEMS v_db_conf; char path[PATH_MAX] = ""; sprintf (path,"%s/%s%s",DBCONF_DIR,dbname,DBCONF_SUFFIX); CONFIG_FILE f_db_conf (path, help_ldap, CONFIGF_OPTIONAL|CONFIGF_MANAGED, mode_slapd_user.get(), mode_slapd_group.get(), 0400, subsys_ldap); name.setfrom (dbname); /* Read config */ v_db_conf.read (f_db_conf); bind.base.setfrom (get_keyval(v_db_conf,"suffix")); bind.dn.setfrom (get_keyval(v_db_conf,"rootdn")); bind.pw.setfrom (get_keyval(v_db_conf,"rootpw")); database.setfrom (get_keyval(v_db_conf,"database")); directory.setfrom (get_keyval(v_db_conf,"directory")); replogfile.setfrom (get_keyval(v_db_conf,"replogfile")); updatedn.setfrom (get_keyval(v_db_conf,"updatedn")); replica.setfrom (get_keyval(v_db_conf,"replica")); lastmod.setfrom (get_keyval(v_db_conf,"lastmod")); readonly.setfrom (get_keyval(v_db_conf,"readonly")); schemacheck.setfrom (get_keyval(v_db_conf,"schemacheck")); loglevel.setfrom (get_keyval(v_db_conf,"loglevel")); defaultaccess.setfrom (get_keyval(v_db_conf,"defaultaccess")); referral.setfrom (get_keyval(v_db_conf,"referral")); return ret; } /*! LDAPDB - export */ PUBLIC int LDAPDB::export_ldif() { char include_indexnumber=true; int ret=0; char dbfile[PATH_MAX] = ""; sprintf (dbfile,"%s/id2entry.dbb",directory.get()); char exportfile [PATH_MAX] = ""; sprintf (exportfile,"/tmp/%s.ldif",name.get()); SSTRING filename(exportfile); int nof; DIALOG dia; dia.newf_str (MSG_U(F_EXPORT_LDIF_FILE,"LDIF Filename"),exportfile,40); dia.newf_chk ("",include_indexnumber,"Include index number "); while (1){ MENU_STATUS code = dia.edit (MSG_U(T_EXPORT_LDIF,"LDIF Export") ,MSG_U(I_EXPORT_LDIF ,"This will export all entries from this database\n" "into a LDIF file.\n" "You must stop the server before you export using this dialog.") ,help_ldap ,nof); if (code == MENU_CANCEL || code == MENU_ESCAPE){ break; } else if (code == MENU_ACCEPT){ char arg[1000] = ""; if (!include_indexnumber) { sprintf (arg,"-n"); } sprintf (arg,"%s > %s",dbfile,exportfile); sys_command_title("LDIF Export","ldbmcat",arg); break; } } return ret; } /*! LDAPDB - LDIF online export */ PUBLIC int LDAPDB::export_ldif(const char *profile_name) { int ret=0; char path [PATH_MAX]; sprintf(path,"/tmp/%s.ldif",profile_name); int nof; SSTRING export_file(path); SSTRING export_filter("objectclass=*"); SSTRING export_attributes(""); SSTRINGS data; LDAPOBJECT ldap; DIALOG dia; dia.newf_str (MSG_U(F_EXPORT_FILE,"Filename"),export_file,40); dia.newf_str (MSG_U(F_EXPORT_FILTER,"Search filter"),export_filter); dia.newf_str (MSG_U(F_EXPORT_ATTR,"Attribute list"),export_attributes); while (1){ MENU_STATUS code = dia.edit (MSG_R(T_EXPORT_LDIF), MSG_U(I_EXPORT_LDIF_ONLINE, "Use this dialog to export data from the directory into the specified file.\n" "The default search filter will include all entries.\n" "The default (empty) attribute list will include all attributes." ), help_ldap, nof); if (code == MENU_CANCEL || code == MENU_ESCAPE){ break; } else if (code == MENU_ACCEPT){ // Setup ldap.load_profile(profile_name); ldap.search_base.setfromf("%s",ldap.bind.base.get()); ldap.filter.setfrom(export_filter.get()); ldap.command_line = export_attributes; // Search ldap.command("ldapsearch",data); int n = data.getnb(); // Write to file FILE *fout = fopen (export_file.get(),"w"); if (fout != NULL){ for (int i=0; iget()); } xconf_notice("Wrote %i lines of LDIF data to file",n); } else { xconf_error("File error"); } break; } } return ret; } /* LDAPDB - Prepare database directory by adding base DN objects */ PUBLIC int LDAPDB::create() { int ret=0; char domain[PATH_MAX]; char conffile[PATH_MAX]; SSTRINGS dc_lst; LDAPOBJECT ldap; char profile_name[PATH_MAX]; // Default database init char add_suffixobject = true; char add_peopleobject = true; char add_groupobject = true; char gen_manager_profile = true; sprintf (conffile,"%s/%s%s",DBCONF_DIR,name.get(),DBCONF_SUFFIX); // Compute DNS domain strcpy(domain,bind.base.get()); dc2list(domain,dc_lst); // DC list dc2dns(domain,sizeof(domain)); int nof; DIALOG dia; dia.newf_chk (MSG_U(F_ADD_DC_DOMAIN,"Add domain DC objects"),add_suffixobject,"Domain"); dia.newf_chk (MSG_U(F_ADD_OU_PEOPLE,"Add people OU object"),add_peopleobject,"People"); dia.newf_chk (MSG_U(F_ADD_OU_GROUP,"Add group OU object"),add_groupobject,"Group"); dia.newf_chk (MSG_U(F_GEN_MANAGER_PROFILE,"Generate manager profile"),gen_manager_profile,"Manager"); while (1){ MENU_STATUS code = dia.edit (MSG_U(T_CREATE,"Create") ,MSG_U(I_CREATE ,"This will init a new database.") ,help_ldap ,nof); if (code == MENU_CANCEL || code == MENU_ESCAPE){ break; } else if (code == MENU_ACCEPT){ char path[PATH_MAX]; CONFIG_FILE *f_profile; CONFDB *c_profile; if (gen_manager_profile) { // Generate a manager profile for this directory sprintf(profile_name,"%s-manager",name.get()); // Generate bind profile sprintf(path,"%s/%s",DBBIND_DIR,profile_name); f_profile = new CONFIG_FILE (path, help_ldap, CONFIGF_MANAGED|CONFIGF_OPTIONAL, "root","root",0600); c_profile = new CONFDB(*f_profile); c_profile->replace("ldap","base",bind.base.get()); c_profile->replace("ldap","host","localhost"); c_profile->replace("ldap","binddn",bind.dn.get()); c_profile->replace("ldap","bindpw",bind.pw.get()); c_profile->save(); delete c_profile; delete f_profile; // Generate directory profile sprintf(path,"%s/%s",PROFILE_DIR,name.get()); f_profile = new CONFIG_FILE (path, help_ldap, CONFIGF_MANAGED|CONFIGF_OPTIONAL, "root","root",0600); c_profile = new CONFDB(*f_profile); char buf[100]; sprintf(buf,"Manager access %s",name.get()); c_profile->replace("profile","comment",buf); // TODO: This could be read from a default profile some day c_profile->replace("profile","bind",profile_name); c_profile->replace("profile","form","account"); c_profile->replace("profile","prefix","ou=People"); c_profile->replace("profile","primarykey","uid"); c_profile->replace("profile","groupprefix","ou=Group"); c_profile->replace("profile","memberkey","memberuid"); c_profile->replace("profile","max_uid",5000000); c_profile->replace("profile","min_uid",10000); c_profile->save(); delete c_profile; delete f_profile; } else { // Need a profile with full access for online init // TODO: Add a root manager (with full access to all server directories) to samples sprintf(profile_name,"%s","root-manager"); } SSTRING line; if (add_suffixobject) { ldap.load_profile(name.get()); ldap.dn.setfromf("dn: %s",bind.base.get()); ldap.at_add("dc",dc_lst.getitem(0)->get()); ldap.oc_add("top"); ldap.oc_add("domain"); ldap.oc_add("domainRelatedObject"); ldap.at_add("associatedDomain",domain); ldap.add(); } if (add_peopleobject) { ldap.load_profile(name.get()); ldap.reset_data(); ldap.dn.setfromf("dn: ou=People,%s",bind.base.get()); ldap.at_add("ou","People"); ldap.oc_add("top"); ldap.oc_add("organizationalUnit"); ldap.oc_add("domainRelatedObject"); ldap.at_add("associatedDomain",domain); ldap.add(); } if (add_groupobject) { ldap.load_profile(name.get()); ldap.reset_data(); ldap.dn.setfromf("dn: ou=Group,%s",bind.base.get()); ldap.at_add("ou","Group"); ldap.oc_add("top"); ldap.oc_add("organizationalUnit"); ldap.oc_add("domainRelatedObject"); ldap.at_add("associatedDomain",domain); ldap.add(); } /* DATABASE INIT OFFLINE MODE (SERVER NOT RUNNING) if (add_suffixobject==true) { fprintf (fout,"dn: %s\n",bind.base.get()); for (int i=0;iget()); } fprintf (fout,"objectClass: top\n"); fprintf (fout,"objectClass: domain\n"); fprintf (fout,"objectClass: domainRelatedObject\n"); fprintf (fout,"associatedDomain: %s\n\n",domain); } if (add_peopleobject==true) { fprintf (fout,"dn: ou=People,%s\n",bind.base.get()); fprintf (fout,"ou: People\n"); fprintf (fout,"objectClass: top\n"); fprintf (fout,"objectClass: organizationalUnit\n"); fprintf (fout,"objectClass: domainRelatedObject\n"); fprintf (fout,"associatedDomain: %s\n\n",domain); } if (add_groupobject==true) { fprintf (fout,"dn: ou=Group,%s\n",bind.base.get()); fprintf (fout,"ou: Group\n"); fprintf (fout,"objectClass: top\n"); fprintf (fout,"objectClass: organizationalUnit\n"); fprintf (fout,"objectClass: domainRelatedObject\n"); fprintf (fout,"associatedDomain: %s\n\n",domain); } fprintf (fout,"\n"); fclose (fout); */ /* Import into database */ /* if (mode_openldap_version == 2) { // OpenLDAP 2.x sprintf (arg,"-l %s -f %s",tmpfile,conffile); // make sure the directory holding the database exist file_mkdirp (directory.get(),SLAPD_USER,SLAPD_GROUP,0700); sys_command_title("DB create","slapadd",arg); } else { // OpenLDAP 1.x sprintf (arg,"-i %s -f %s",tmpfile,conffile); // make sure the directory holding the database exist file_mkdirp (directory.get(),0,0,0700); sys_command_title("DB create","ldif2ldbm",arg); // OpenLDAP 1.x */ break; } } return ret; } /*! LDAPDB - import_ldif This is designed to import a Netscape exported addressbook in LDIF format. Currently it just add the suffix to the database and import. */ PUBLIC int LDAPDB::import_ldif() { int ret=0; char add_suffix=true; char add_suffixobject=true; char conffile[PATH_MAX] = ""; sprintf (conffile,"%s/%s%s",DBCONF_DIR,name.get(),DBCONF_SUFFIX); char importfile [PATH_MAX] = ""; sprintf (importfile,"/tmp/%s.ldif",name.get()); SSTRING filename(importfile); SSTRING profile; int nof; LDAPOBJECT ldap; profile.setfrom(name.get()); DIALOG dia; dia.newf_str (MSG_U(F_IMPORT_LDIF_FILE,"LDIF Filename"),importfile,40); dia.newf_str (MSG_U(F_IMPORT_LDIF_PROFILE,"Use directory profile"),profile,40); dia.newf_chk ("Add base DN to all objects",add_suffix,"Domain base"); dia.newf_chk ("Add base object to directory",add_suffixobject,"Domain base"); while (1){ MENU_STATUS code = dia.edit (MSG_U(T_IMPORT_LDIF,"LDIF Import") ,MSG_U(I_IMPORT_LDIF ,"Import LDIF entries file into directory") ,help_ldap ,nof); if (code == MENU_CANCEL || code == MENU_ESCAPE){ break; } else if (code == MENU_ACCEPT){ ldap.load_profile(profile.get()); // Parse all input data, manipulate if needed, and write to tmp file FILE *fin = fopen(importfile,"r"); FILE *fout = fopen(ldap.gettmpfile(),"w"); if ((fin != NULL)) { SSTRING line; char buf[1000]; int n=0; if (add_suffixobject==true) { // Add domain object fprintf (fout,"dn: %s\n",bind.base.get()); fprintf (fout,"%s\n",bind.base.get()); fprintf (fout,"objectclass: top\n"); fprintf (fout,"objectclass: domain\n"); fprintf (fout,"\n"); } while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ strip_end(buf); line.setfrom(buf); if (line.strstr("dn:")){ // DN entry n++; // Count it if (add_suffixobject==true){ // Add domain suffix to DN line.appendf(",%s",bind.base.get()); } D(debugf(5,"Adding object count=%i %s",n,line.get())); } fprintf (fout,"%s\n",line.get()); } fclose (fin); fclose (fout); // Now add the new ldif file to the directory // TODO: Move this to ldap_object as a new importfile method ldap.command_line.setfrom(" -a"); // Add ldap.command_line.appendf(" -f %s",ldap.gettmpfile()); // Entry SSTRINGS resmsg; ret = ldap.command ("ldapmodify",resmsg); unlink(ldap.gettmpfile()); logf(LOG_NORMAL,"Importing LDIF file %s using profile %s",importfile,profile.get()); } break; } } return ret; /* LDIF IMPORT OFFLINE MODE (SERVER NOT RUNNING) char tmpfile[PATH_MAX] = "/tmp/import.ldif.tmp"; FILE *fin = fopen(importfile,"r"); FILE *fout = fopen (tmpfile,"w"); if ((fin != NULL)&&(fout != NULL)) { char buf[1000]; SSTRING line; if (add_suffixobject==true) { fprintf (fout,"dn: %s\n",bind.base.get()); fprintf (fout,"%s\n",bind.base.get()); fprintf (fout,"objectclass: top\n"); fprintf (fout,"objectclass: domain\n"); } fprintf (fout,"\n"); while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ strip_end(buf); line.setfrom(buf); // xconf_notice(buf); if ((line.strstr("dn:")!=NULL)&&(add_suffixobject==true)) char newdn[ATTR_VAL_MAX]; snprintf(newdn,ATTR_VAL_MAX,",%s",bind.base.get()); line.append(newdn); } fprintf (fout,"%s\n",line.get()); } fclose (fout); fclose (fin); if (mode_openldap_version == 2) { // OpenLDAP 2.x sprintf (arg,"-l %s -f %s",tmpfile,conffile); // make sure the directory holding the database exist file_mkdirp (directory.get(),SLAPD_USER,SLAPD_GROUP,0700); sys_command_title("LDIF import","slapadd",arg); } else { // OpenLDAP 1.x sprintf (arg,"-i %s -f %s",tmpfile,conffile); // make sure the directory holding the database exist file_mkdirp (directory.get(),0,0,0700); sys_command_title("LDIF import","ldif2ldbm",arg); // OpenLDAP 1.x } } */ } /* Database config */ PUBLIC void LDAPDB::config(const char *dbname){ CONFIG_FILE f_slapd_conf ("slapd.conf", help_ldap, CONFIGF_OPTIONAL|CONFIGF_MANAGED, mode_slapd_user.get(), mode_slapd_group.get(), 0400, subsys_ldap); VIEWITEMS v_db_conf; VIEWITEMS v_slapd_conf; char was_enabled = false; char enable_database = true; char acl_selfwrite = true; // Sample ACL for self write access char index_nss = true; // Sample indexing to improve nss performance char path[PATH_MAX] = ""; /* Calculate filename */ sprintf (path,"%s/%s%s",DBCONF_DIR,dbname,DBCONF_SUFFIX); /* Check if this db is enabled in slapd.conf */ VIEWITEMS inc_items; VIEWITEM *inc_item=NULL; v_slapd_conf.read (f_slapd_conf); int n = v_slapd_conf.locate("include",inc_items); for (int i=0; iline.strstr(path)!=0) { enable_database = true; was_enabled = true; break; /* inc_item will point to this db entry */ } } SSTRING filename(path); filename.strip_end(); /* Draw dialog */ DIALOG dia; dia.newf_title (MSG_U(I_GENERAL_PARAM,"General"),1,"",MSG_R(I_GENERAL_PARAM)); dia.newf_chk (MSG_U(F_DB_ENABLE,"Enable database"),enable_database," "); dia.newf_str (MSG_U(F_DB_PROFILE,"Config file"),filename); FIELD_COMBO *dblist = dia.newf_combo(MSG_U(F_SLAPD_DATABASE,"Database type"),database); dblist->addopt ("ldbm"); dblist->addopt ("shell"); dblist->addopt ("passwd"); dia.newf_str (MSG_U(F_DB_DIRECTORY,"LDBM directory path"),directory); FIELD_COMBO *readonly_key = dia.newf_combo (MSG_U(F_DB_READONLY,"Readonly"),readonly); readonly_key->addopt ("on"); readonly_key->addopt ("off"); FIELD_COMBO *schema = dia.newf_combo(MSG_U(F_DB_SCHEMACHECK,"Schemacheck"),schemacheck); schema->addopt ("on"); schema->addopt ("off"); dia.newf_str (MSG_U(F_DB_LOGLEVEL,"Loglevel"),loglevel); FIELD_COMBO *accesslist = dia.newf_combo(MSG_U(F_DB_DEFAULTACCESS,"Default access"),defaultaccess); accesslist->addopt ("none"); accesslist->addopt ("compare"); accesslist->addopt ("search"); accesslist->addopt ("read"); accesslist->addopt ("write"); // accesslist->addopt ("delete"); dia.newf_str (MSG_U(F_DB_REFERRAL,"Referral"),referral); dia.newf_title (MSG_U(I_MASTER_DATABASE,"Root"),1,"",MSG_R(I_MASTER_DATABASE)); dia.newf_str (MSG_R(F_API_BASE),bind.base); dia.newf_str (MSG_R(F_API_DN),bind.dn); dia.newf_str (MSG_R(F_API_PW),bind.pw); dia.newf_title (MSG_U(I_MASTER_PARAM,"Master"),1,"",MSG_R(I_MASTER_PARAM)); FIELD_COMBO *lastmod_key= dia.newf_combo (MSG_U(F_DB_LASTMOD,"Lastmod recording"),lastmod); lastmod_key->addopt ("on"); lastmod_key->addopt ("off"); dia.newf_str (MSG_U(F_DB_REPLOG,"Replicaton log"),replogfile); dia.newf_str (MSG_U(F_DB_REPLICA,"Replica host"),replica); dia.newf_title (MSG_U(I_SLAVE_PARAM,"Slave"),1,"",MSG_R(I_SLAVE_PARAM)); dia.newf_str (MSG_U(F_DB_UPDATEDN,"Update DN"),updatedn); dia.newf_title (MSG_U(I_ACL_PARAM,"Access Control List (ACL)"),1,"",MSG_R(I_ACL_PARAM)); dia.newf_chk (MSG_U(F_ACL_SELFWRITE,"Add ACL for"),acl_selfwrite,"update of SELF object"); // dia.newf_title (MSG_U(I_ACCESS_PARAM,"Attributes"),1,"",""); // dia.newf_info ("","Not done"); dia.newf_title (MSG_U(I_INDEXES_PARAM,"Indexing"),1,"",MSG_R(I_INDEXES_PARAM)); dia.newf_chk (MSG_U(F_INDEX_NSS,"Use index on"),index_nss,"NIS keys"); // dia.setbutinfo (MENU_USR1,MSG_U(B_EXPORT,"Export") // ,MSG_U(X_EXPORT,"Export")); // dia.setbutinfo (MENU_USR2,MSG_U(B_IMPORT,"Import") // ,MSG_U(X_IMPORT,"Import")); /* Dialog */ int nof = 0; while (1){ MENU_STATUS code = dia.edit (MSG_U(T_DATABASE_MENU,"LDAP database") ,MSG_U(I_DATABASE_MENU ,"Here you may configure a LDAP directory.\n" "Currently ldapconf will save directory setting in individual files,\n" "and then include this files in the main slapd.conf file.\n" "You may still have database settings in the main file,\n" "but ldapconf will not operate on those.") ,help_ldap ,nof ,MENUBUT_ACCEPT|MENUBUT_CANCEL); /* Exit */ if (code == MENU_CANCEL || code == MENU_ESCAPE){ break; } // /* Export */ else if (code == MENU_USR1){ // export_ldif(); // } // /* Import */ else if (code == MENU_USR2){ // import_ldif(); // } /* Save */ else if (code == MENU_ACCEPT){ set_keyval(v_db_conf,"database",database.get()); set_keyval(v_db_conf,"suffix",bind.base.get()); set_keyval(v_db_conf,"rootdn",bind.dn.get()); set_keyval(v_db_conf,"rootpw",bind.pw.get()); set_keyval(v_db_conf,"directory",directory.get()); set_keyval(v_db_conf,"readonly",readonly.get()); set_keyval(v_db_conf,"lastmod",lastmod.get()); set_keyval(v_db_conf,"replogfile",replogfile.get()); set_keyval(v_db_conf,"replica",replica.get()); set_keyval(v_db_conf,"updatedn",updatedn.get()); set_keyval(v_db_conf,"schemacheck",schemacheck.get()); set_keyval(v_db_conf,"loglevel",loglevel.get()); set_keyval(v_db_conf,"defaultaccess",defaultaccess.get()); set_keyval(v_db_conf,"referral",referral.get()); if (acl_selfwrite){ // ACL - provide a generic ACL setup until a better interface is written v_db_conf.add(new VIEWITEM("access to attr=userpassword by self write by * compare")); v_db_conf.add(new VIEWITEM("access to * by self write")); } if (index_nss) { // INDEX - provide a generic INDEX setup until a better interface is written v_db_conf.add(new VIEWITEM("index objectclass,uid,uidNumber,gidNumber\teq")); v_db_conf.add(new VIEWITEM("index cn,mail,surname,givenname\teq,subinitial")); } CONFIG_FILE f_db_conf_save (path, help_ldap, CONFIGF_OPTIONAL|CONFIGF_MANAGED, mode_slapd_user.get(), mode_slapd_group.get(), 0400, subsys_ldap); v_db_conf.write (f_db_conf_save,&p_ldap_admin); if (enable_database && !was_enabled) { char buf[1000]; VIEWITEM *it; sprintf(buf,"%s %s","include",path); it = new VIEWITEM(buf); v_slapd_conf.add(it); /* add db entry */ logf(LOG_NOTICE,"Enabling database profile %s",path); } else if (was_enabled && !enable_database) { inc_item->line.setfrom(""); /* remove db entry */ logf(LOG_NOTICE,"Disabling database profile %s",path); } v_slapd_conf.write(f_slapd_conf,&p_ldap_admin); // Confirm server restart (needed for activation, but restart may fail if something is wrong) if (xconf_yesno(MSG_U(T_SERVER_RESTART_OK,"Confirm server restart"), MSG_U(I_SERVER_RESTART_OK, "To activate the changes, the server must be restarted.\n" "But be aware that if anything is wrong in the new configuration\n" "the server may refuse to start. This may be critical if the server\n" "is publishing production critical directory data to clients.\n" "Do you want to restart the server now?\n" ), help_ldap) == MENU_YES){ sys_command_title ("Server restart","slapd.init","restart"); } break; } } } /* Database command menu */ PUBLIC void LDAPDB::menu() { const char *config_key = MSG_U(M_DB_CONFIG,"Configure database"); const char *create_key = MSG_U(M_DB_CREATE,"Init a new empty database"); const char *export_key = MSG_U(M_DB_EXPORT,"Export from directory to LDIF file"); const char *import_key = MSG_U(M_DB_IMPORT,"Import from LDIF file to directory"); const char *migrate_key = MSG_U(M_DB_MIGRATE,"Migrate from system to directory"); DIALOG_MENU dia; dia.new_menuinfo("Database name",name.get()); dia.new_menuitem("Config database",config_key); dia.new_menuitem("Init database",create_key); dia.new_menuitem("Export LDIF",export_key); dia.new_menuitem("Import LDIF",import_key); dia.new_menuitem("Import users",migrate_key); int nof = 0; while (1){ MENU_STATUS code = dia.editmenu (MSG_U(T_DB_MENU,"Database menu") ,MSG_U(I_DB_MENU,"Select an operation to perform on this database") ,help_ldap ,nof,0); const char *key = dia.getmenustr(nof); if (code == MENU_ESCAPE || code == MENU_QUIT){ break; }else{ if (key == config_key){ config(name.get()); }else if (key == export_key){ export_ldif(name.get()); }else if (key == import_key){ import_ldif(); }else if (key == migrate_key){ ldap_migrate_users(name.get()); }else if (key == create_key){ create(); } } } }