1 /* 2 *---------------------------------------------------------------------------- 3 * 4 * msktutil.h 5 * 6 * (C) 2004-2006 Dan Perry (dperry@pppl.gov) 7 * (C) 2006 Brian Elliott Finley (finley@anl.gov) 8 * (C) 2009-2010 Doug Engert (deengert@anl.gov) 9 * (C) 2010 James Y Knight (foom@fuhm.net) 10 * (C) 2010-2013 Ken Dreyer <ktdreyer at ktdreyer.com> 11 * (C) 2012-2017 Mark Proehl <mark at mproehl.net> 12 * (C) 2012-2017 Olaf Flebbe <of at oflebbe.de> 13 * (C) 2013-2017 Daniel Kobras <d.kobras at science-computing.de> 14 * 15 This program is free software; you can redistribute it and/or modify 16 it under the terms of the GNU General Public License as published by 17 the Free Software Foundation; either version 2 of the License, or 18 (at your option) any later version. 19 20 This program is distributed in the hope that it will be useful, 21 but WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 GNU General Public License for more details. 24 25 You should have received a copy of the GNU General Public License 26 along with this program; if not, write to the Free Software 27 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 28 * 29 *----------------------------------------------------------------------------- 30 */ 31 32 #ifndef __msktutil_h__ 33 #define __msktutil_h__ 34 35 36 #include "config.h" 37 38 #include <stdio.h> 39 #include <stdarg.h> 40 #include <fcntl.h> 41 #include <string.h> 42 #include <unistd.h> 43 #include <signal.h> 44 #include <ctype.h> 45 #include <stdlib.h> 46 #include <errno.h> 47 #include <time.h> 48 #include <limits.h> 49 #include <netdb.h> 50 #include <netinet/in.h> 51 #include <sys/socket.h> 52 #include <sys/utsname.h> 53 #include <ldap.h> 54 #include <list> 55 56 #ifdef HAVE_COM_ERR_H 57 # ifdef COM_ERR_NEEDS_EXTERN_C 58 extern "C" { 59 # endif 60 #include <com_err.h> 61 # ifdef COM_ERR_NEEDS_EXTERN_C 62 } 63 # endif 64 #endif 65 #include <krb5.h> 66 67 68 #include <stdexcept> 69 #include <string> 70 #include <vector> 71 #include <memory> 72 73 #ifndef PACKAGE_NAME 74 #define PACKAGE_NAME "msktutil" 75 #endif 76 #define PASSWORD_LEN 63 77 #define MAX_HOSTNAME_LEN 255 78 #define MAX_TRIES 10 79 #define MAX_SAM_ACCOUNT_LEN 20 80 #define MAX_DEF_MACH_PASS_LEN 14 81 #define MAX_DOMAIN_CONTROLLERS 20 82 83 84 #ifndef TMP_DIR 85 #define TMP_DIR "/tmp" 86 #endif 87 88 89 /* In case it's not in krb5.h */ 90 #ifndef MAX_KEYTAB_NAME_LEN 91 #define MAX_KEYTAB_NAME_LEN 1100 92 #endif 93 94 /* From SAM.H */ 95 #define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000 96 #define UF_ACCOUNT_DISABLE 0x00000002 97 #define UF_NORMAL_ACCOUNT 0x00000200 98 #define UF_DONT_EXPIRE_PASSWORD 0x00010000 99 #define UF_TRUSTED_FOR_DELEGATION 0x00080000 100 #define UF_USE_DES_KEY_ONLY 0x00200000 101 #define UF_NO_AUTH_DATA_REQUIRED 0x02000000 102 103 /* for msDs-supportedEncryptionTypes bit defines */ 104 #define MS_KERB_ENCTYPE_DES_CBC_CRC 0x01 105 #define MS_KERB_ENCTYPE_DES_CBC_MD5 0x02 106 #define MS_KERB_ENCTYPE_RC4_HMAC_MD5 0x04 107 108 /* Define these if the system supports them, otherwise define to 0. */ 109 #if HAVE_DECL_ENCTYPE_AES128_CTS_HMAC_SHA1_96 110 #define MS_KERB_ENCTYPE_AES128_CTC_HMAC_SHA1_96 0x08 111 #else 112 #define MS_KERB_ENCTYPE_AES128_CTC_HMAC_SHA1_96 0 113 #endif 114 115 #if HAVE_DECL_ENCTYPE_AES128_CTS_HMAC_SHA1_96 116 #define MS_KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x10 117 #else 118 #define MS_KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 0 119 #endif 120 121 /* Some KVNO Constansts */ 122 #define KVNO_FAILURE -1 123 #define KVNO_WIN_2000 0 124 125 /* Ways we can authenticate */ 126 enum auth_types { 127 AUTH_NONE = 0, 128 AUTH_FROM_SAM_KEYTAB, 129 AUTH_FROM_SAM_UPPERCASE_KEYTAB, 130 AUTH_FROM_HOSTNAME_KEYTAB, 131 AUTH_FROM_PASSWORD, 132 AUTH_FROM_USER_CREDS, 133 AUTH_FROM_SUPPLIED_PASSWORD, 134 AUTH_FROM_SUPPLIED_EXPIRED_PASSWORD, 135 AUTH_FROM_EXPLICIT_KEYTAB, 136 }; 137 138 class LDAPConnection; 139 140 enum msktutil_val { 141 VALUE_OFF = 0, 142 VALUE_ON = 1, 143 VALUE_IGNORE = 2 144 }; 145 146 extern int g_verbose; 147 148 enum msktutil_mode { 149 MODE_NONE = 0, 150 MODE_CREATE, 151 MODE_UPDATE, 152 MODE_AUTO_UPDATE, 153 MODE_FLUSH, 154 MODE_CLEANUP, 155 MODE_PRECREATE, 156 MODE_DELETE 157 }; 158 159 160 class msktutil_flags { 161 public: 162 std::string keytab_file; 163 std::string keytab_writename; 164 std::string keytab_readname; 165 std::string keytab_auth_princ; 166 std::string ldap_ou; 167 std::string hostname; 168 std::string description; 169 std::string server; 170 std::string realm_name; 171 std::string lower_realm_name; 172 std::string base_dn; 173 std::string sAMAccountName; 174 std::string sAMAccountName_nodollar; 175 std::string sAMAccountName_uppercase; 176 std::string password; 177 bool password_from_cmdline; 178 std::string userPrincipalName; 179 std::string old_account_password; 180 std::string site; 181 LDAPConnection* ldap; 182 std::string ad_computerDn; 183 std::string ad_dnsHostName; 184 std::vector<std::string> ad_principals; 185 186 bool set_userPrincipalName; 187 bool no_reverse_lookups; 188 bool no_canonical_name; 189 bool server_behind_nat; 190 bool set_samba_secret; 191 bool check_replication; 192 bool dont_change_password; 193 194 msktutil_val dont_expire_password; 195 msktutil_val dont_update_dnshostname; 196 msktutil_val disable_account; 197 msktutil_val no_pac; 198 msktutil_val delegate; 199 unsigned int ad_userAccountControl; /* value AD has now */ 200 int ad_enctypes; /* if msDs-supportedEncryptionTypes in AD */ 201 unsigned int ad_supportedEncryptionTypes; /* value AD has now */ 202 int enctypes; /* if --enctypes parameter was set */ 203 unsigned int supportedEncryptionTypes; 204 205 int auth_type; 206 bool user_creds_only; 207 bool use_service_account; 208 bool allow_weak_crypto; 209 bool password_expired; 210 int auto_update_interval; 211 krb5_kvno kvno; 212 int cleanup_days; 213 int cleanup_enctype; 214 msktutil_flags(); 215 216 private: 217 msktutil_flags operator=(const msktutil_flags& other); 218 msktutil_flags(const msktutil_flags& other); 219 ~msktutil_flags(); 220 }; 221 222 class msktutil_exec { 223 public: 224 msktutil_mode mode; 225 std::vector<std::string> add_principals; 226 std::vector<std::string> remove_principals; 227 228 msktutil_exec(); 229 230 ~msktutil_exec(); 231 void set_mode(msktutil_mode mode); 232 }; 233 234 235 class Globals { 236 msktutil_flags* _flags; 237 msktutil_exec* _exec; 238 static Globals *instance; 239 240 public: 241 static Globals* get(); flags()242 static msktutil_flags *flags() { 243 return Globals::get()->_flags; 244 } exec()245 static msktutil_exec *exec() { 246 return Globals::get()->_exec; 247 } 248 void set_supportedEncryptionTypes(char * value); 249 }; 250 251 /* Prototypes */ 252 extern std::string create_default_machine_password(const std::string &sAMAccountName); 253 extern void ldap_cleanup(msktutil_flags *); 254 extern void init_password(msktutil_flags *); 255 extern std::string get_default_hostname(bool no_canonical_name = false); 256 extern void get_default_keytab(msktutil_flags *); 257 extern std::string get_salt(msktutil_flags *); 258 extern void get_default_ou(msktutil_flags *); 259 260 extern void ldap_get_base_dn(msktutil_flags *); 261 extern std::string complete_hostname(const std::string &, 262 bool no_canonical_name = false); 263 extern std::string get_default_samaccountname(msktutil_flags *); 264 extern std::string get_short_hostname(msktutil_flags *); 265 extern int flush_keytab(msktutil_flags *); 266 extern void cleanup_keytab(msktutil_flags *); 267 extern void update_keytab(msktutil_flags *); 268 extern void add_keytab_entries(msktutil_flags *); 269 extern void remove_keytab_entries(msktutil_flags *,std::vector<std::string>); 270 extern void add_principal_keytab(const std::string &, msktutil_flags *); 271 extern int ldap_flush_principals(msktutil_flags *); 272 extern int set_password(msktutil_flags *); 273 extern krb5_kvno ldap_get_kvno(msktutil_flags *); 274 extern std::string ldap_get_pwdLastSet(msktutil_flags *); 275 extern std::vector<std::string> ldap_list_principals(msktutil_flags *); 276 extern int ldap_add_principal(const std::string &, msktutil_flags *); 277 int ldap_remove_principal(const std::string &principal, msktutil_flags *flags); 278 extern std::string get_dc_host(const std::string &realm_name, const std::string &site_name, 279 const bool); 280 extern std::string get_host_os(); 281 extern bool ldap_check_account(msktutil_flags *); 282 extern void ldap_create_account(msktutil_flags *); 283 extern void create_fake_krb5_conf(msktutil_flags *); 284 extern void remove_fake_krb5_conf(); 285 extern void remove_ccache(); 286 int find_working_creds(msktutil_flags *flags); 287 bool get_creds(msktutil_flags *flags); 288 int generate_new_password(msktutil_flags *flags); 289 290 /* Verbose messages */ 291 #define VERBOSE(text...) if (g_verbose) { fprintf(stdout, " -- %s: ", __FUNCTION__); fprintf(stdout, ## text); fprintf(stdout, "\n"); } 292 293 /* Fatal error */ 294 void error_exit(const char *text); 295 296 /* To be used by higher level error messages, like krb5 */ 297 void v_error_exit(const char* format, ...); 298 299 /* printf into a C++ string. */ 300 std::string sform(const char* format, ...); 301 302 class Exception : public std::exception 303 { 304 protected: 305 std::string m_message; 306 307 /* Prohibit assignment */ 308 Exception& operator=(const Exception&); 309 310 public: 311 /* Constructors */ 312 313 /* Default construction with no message uses "Exception" */ Exception()314 Exception() : m_message("Exception") { } Exception(char const * simple_string)315 explicit Exception(char const * simple_string) : m_message(simple_string) {} Exception(const std::string & str)316 explicit Exception(const std::string &str) : m_message(str) {} Exception(const Exception & src)317 Exception(const Exception& src) : exception(), m_message(src.m_message) {} 318 ~Exception()319 virtual ~Exception() throw() {}; what()320 char const * what() const throw() { return m_message.c_str(); } 321 }; 322 323 class KRB5Exception : public Exception 324 { 325 protected: 326 krb5_error_code m_err; 327 public: KRB5Exception(const std::string & func,krb5_error_code err)328 explicit KRB5Exception(const std::string &func, krb5_error_code err) : 329 Exception(sform("Error: %s failed (%s)", func.c_str(), error_message(err))) 330 { m_err = err; } err()331 krb5_error_code err() const throw() { return m_err; } 332 333 }; 334 335 class LDAPException : public Exception 336 { 337 public: LDAPException(const std::string & func,int err)338 explicit LDAPException(const std::string &func, int err) : 339 Exception(sform("Error: %s failed (%s)", func.c_str(), ldap_err2string(err))) 340 {} 341 }; 342 343 #ifdef __GNUC__ 344 #define ATTRUNUSED __attribute__((unused)) 345 #else 346 #define ATTRUNUSED 347 #endif 348 349 350 #include "krb5wrap.h" 351 #include "ldapconnection.h" 352 #include "msktname.h" 353 354 355 356 #endif 357 358