diff --git a/cmdline/main.cpp b/cmdline/main.cpp index a42b8d7..97e077b 100644 --- a/cmdline/main.cpp +++ b/cmdline/main.cpp @@ -18,6 +18,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include + #include #include #include @@ -48,13 +50,18 @@ static const char version[] = "v0.0.1"; static const TDECmdLineOptions options[] = { { "forcepwchangenextlogin", I18N_NOOP("Force the user to change password on next login"), 0 }, - { "username ", I18N_NOOP("Specifies the user name in the Kerberos realm"), 0 }, - { "password ", I18N_NOOP("Sets the password for the specified account to the given value"), 0 }, + { "username ", I18N_NOOP("Specifies the user name in the Kerberos realm (mandatory)"), 0 }, + { "uid ", I18N_NOOP("Specifies the POSIX user ID in the Kerberos realm"), 0 }, + { "password ", I18N_NOOP("Sets the password for the specified account to the given value"), 0 }, + { "displayname ", I18N_NOOP("Sets the display name (common name) of the specified account to the given value"), 0 }, + { "homedirectory ", I18N_NOOP("Sets the home directory of the specified account to the given value"), 0 }, { "givenname ", I18N_NOOP("Sets the first name of the specified account to the given value"), 0 }, { "surname ", I18N_NOOP("Sets the last name of the specified account to the given value"), 0 }, { "group ", I18N_NOOP("Sets membership of the specified account in the groups listed on the command line, and revokes membership in any groups not listed. This option may be used multiple times."), 0 }, { "revokeallgroups", I18N_NOOP("Revokes membership of the specified account for all groups"), 0 }, - { "!+command", I18N_NOOP("The command to execute on the Kerberos realm. Valid commands are: adduser"), 0 }, + { "adminusername ", I18N_NOOP("Specifies the username of the administrative user with permissions to perform the requested task"), 0 }, + { "adminpasswordfile ", I18N_NOOP("Specifies the location of a file which contains the password of the administrative user"), 0 }, + { "!+command", I18N_NOOP("The command to execute on the Kerberos realm. Valid commands are: adduser deluser"), 0 }, { "!+realm", I18N_NOOP("The Kerberos realm on which to execute the specified command. Example: MY.REALM"), 0 }, { "", I18N_NOOP("This utility will use GSSAPI to connect to the realm controller. You must own an active, valid Kerberos ticket in order to use this utility!"), 0 }, TDECmdLineLastOption // End of options. @@ -96,7 +103,22 @@ int main(int argc, char *argv[]) systemconfig.setGroup("LDAPRealm-" + realm); TQString host = systemconfig.readEntry("admin_server"); LDAPCredentials credentials; - credentials.use_gssapi = true; + if (args->isSet("adminusername") && args->isSet("adminpasswordfile")) { + TQString passFileName = args->getOption("adminpasswordfile"); + TQFile passFile(passFileName); + if (!passFile.open(IO_ReadOnly)) { + printf("[ERROR] Unable to open specified password file '%s'\n\r", passFileName.ascii()); fflush(stdout); + return -1; + } + TQTextStream stream(&passFile); + credentials.username = args->getOption("adminusername"); + credentials.password = stream.readLine(); + passFile.close(); + } + else { + credentials.use_gssapi = true; + } + credentials.realm = realm; LDAPManager ldapmanager(realm, host, &credentials); if (command == "adduser") { @@ -120,21 +142,56 @@ int main(int argc, char *argv[]) } // Find the next available, reasonable UID - uid_t uid = 100; - LDAPUserInfoList::Iterator it; - for (it = userInfoList.begin(); it != userInfoList.end(); ++it) { - LDAPUserInfo user = *it; - if (user.uid >= uid) { - uid = user.uid + 1; + if (args->isSet("uid")) { + uid_t uid = atoi(args->getOption("uid")); + LDAPUserInfoList::Iterator it; + for (it = userInfoList.begin(); it != userInfoList.end(); ++it) { + LDAPUserInfo user = *it; + if (user.uid == uid) { + printf("[ERROR] The specified POSIX user ID is already in use\n\r"); + return -1; + } + } + user.uid = uid; + } + else { + uid_t uid = 100; + LDAPUserInfoList::Iterator it; + for (it = userInfoList.begin(); it != userInfoList.end(); ++it) { + LDAPUserInfo user = *it; + if (user.uid >= uid) { + uid = user.uid + 1; + } } + user.uid = uid; + } + + if (!args->isSet("username")) { + printf("[ERROR] You must specify a username when adding a user\n\r"); + return -1; + } + if (!args->isSet("surname")) { + printf("[ERROR] You must specify a surname when adding a user\n\r"); + return -1; } - user.uid = uid; // Get user data user.name = args->getOption("username"); user.new_password = args->getOption("password"); user.givenName = args->getOption("givenname"); user.surName = args->getOption("surname"); + if (args->isSet("displayname")) { + user.commonName = args->getOption("displayname"); + } + else { + user.commonName = user.givenName + " " + user.surName; + } + if (args->isSet("homedirectory")) { + user.homedir = args->getOption("homedirectory"); + } + else { + user.homedir = "/home/" + user.name; + } // Get list of groups QCStringList groupList = args->getOptionList("group"); @@ -151,7 +208,7 @@ int main(int argc, char *argv[]) else { user.distinguishedName = "uid=" + user.name + "," + ldapmanager.basedn(); } - if (ldapmanager.addUserInfo(user) == 0) { + if (ldapmanager.addUserInfo(user, &errorString) == 0) { // Modify group(s) as needed bool revoke_all = args->isSet("revokeallgroups"); if ((groupList.count() > 0) || revoke_all) { @@ -167,14 +224,14 @@ int main(int argc, char *argv[]) // Make sure that we are in this group! if (!group.userlist.contains(user.distinguishedName)) { group.userlist.append(user.distinguishedName); - ldapmanager.updateGroupInfo(group); + ldapmanager.updateGroupInfo(group, &errorString); } } else { // Make sure that we are NOT in this group! if (group.userlist.contains(user.distinguishedName)) { group.userlist.remove(user.distinguishedName); - ldapmanager.updateGroupInfo(group); + ldapmanager.updateGroupInfo(group, &errorString); } } } @@ -182,13 +239,55 @@ int main(int argc, char *argv[]) if (user.new_password != "") { // If a new password was set, use Kerberos to set it on the server - errorString = TQString::null; if (ldapmanager.setPasswordForUser(user, &errorString) != 0) { printf("[ERROR] Unable to set password for user\n\r[ERROR] Detailed debugging information: %s\n\r", errorString.ascii()); } - ldapmanager.unbind(true); // Using kadmin on admin users/groups can disrupt our LDAP connection (likely due to the ACL rewrite) } } + else { + printf("[ERROR] Unable to add user with distingushed name '%s'\n\r[ERROR] Detailed debugging information: %s\n\r", user.distinguishedName.ascii(), errorString.ascii()); + } + } + else if (command == "deluser") { + LDAPUserInfo deluser; + + TQString errorString; + if (ldapmanager.bind(&errorString) != 0) { + printf("[ERROR] Unable to bind to Kerberos realm controller\n\r[ERROR] Detailed debugging information: %s\n\r", errorString.ascii()); + return -1; + } + + LDAPUserInfoList userInfoList = ldapmanager.users(&retcode); + if (retcode != 0) { + printf("[ERROR] Unable to retrieve list of users from realm controller\n\r"); + return -1; + } + + if (!args->isSet("username")) { + printf("[ERROR] You must specify a username when deleting a user\n\r"); + return -1; + } + + TQString delUserName = args->getOption("username"); + + bool found = false; + LDAPUserInfoList::Iterator it; + for (it = userInfoList.begin(); it != userInfoList.end(); ++it) { + LDAPUserInfo user = *it; + if (user.name == delUserName) { + found = true; + deluser = user; + break; + } + } + if (found) { + ldapmanager.deleteUserInfo(deluser); + } + else { + printf("[ERROR] User not found\n\r"); + return -1; + } + // FIXME } else { TDECmdLineArgs::usage(i18n("An invalid command was specified")); diff --git a/subdirs b/subdirs index 4eb573f..5d6cfe2 100644 --- a/subdirs +++ b/subdirs @@ -1,4 +1,4 @@ +cmdline doc po -cmdline src