root/source4/auth/credentials/credentials.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cli_credentials_init
  2. cli_credentials_init_anon
  3. cli_credentials_set_kerberos_state
  4. cli_credentials_get_kerberos_state
  5. cli_credentials_set_gensec_features
  6. cli_credentials_get_gensec_features
  7. cli_credentials_get_username
  8. cli_credentials_set_username
  9. cli_credentials_set_username_callback
  10. cli_credentials_set_bind_dn
  11. cli_credentials_get_bind_dn
  12. cli_credentials_get_principal
  13. cli_credentials_set_principal
  14. cli_credentials_set_principal_callback
  15. cli_credentials_authentication_requested
  16. cli_credentials_get_password
  17. cli_credentials_set_password
  18. cli_credentials_set_password_callback
  19. cli_credentials_get_old_password
  20. cli_credentials_set_old_password
  21. cli_credentials_get_nt_hash
  22. cli_credentials_get_domain
  23. cli_credentials_set_domain
  24. cli_credentials_set_domain_callback
  25. cli_credentials_get_realm
  26. cli_credentials_set_realm
  27. cli_credentials_set_realm_callback
  28. cli_credentials_get_workstation
  29. cli_credentials_set_workstation
  30. cli_credentials_set_workstation_callback
  31. cli_credentials_parse_string
  32. cli_credentials_get_unparsed_name
  33. cli_credentials_set_conf
  34. cli_credentials_guess
  35. cli_credentials_set_netlogon_creds
  36. cli_credentials_get_netlogon_creds
  37. cli_credentials_set_secure_channel_type
  38. cli_credentials_get_secure_channel_type
  39. cli_credentials_set_anonymous
  40. cli_credentials_is_anonymous
  41. cli_credentials_wrong_password

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    User credentials handling
   5 
   6    Copyright (C) Jelmer Vernooij 2005
   7    Copyright (C) Tim Potter 2001
   8    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
   9    
  10    This program is free software; you can redistribute it and/or modify
  11    it under the terms of the GNU General Public License as published by
  12    the Free Software Foundation; either version 3 of the License, or
  13    (at your option) any later version.
  14    
  15    This program is distributed in the hope that it will be useful,
  16    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18    GNU General Public License for more details.
  19    
  20    You should have received a copy of the GNU General Public License
  21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  22 */
  23 
  24 #include "includes.h"
  25 #include "librpc/gen_ndr/samr.h" /* for struct samrPassword */
  26 #include "auth/credentials/credentials.h"
  27 #include "auth/credentials/credentials_krb5.h"
  28 #include "auth/credentials/credentials_proto.h"
  29 #include "libcli/auth/libcli_auth.h"
  30 #include "lib/events/events.h"
  31 #include "param/param.h"
  32 
  33 /**
  34  * Create a new credentials structure
  35  * @param mem_ctx TALLOC_CTX parent for credentials structure 
  36  */
  37 _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) 
     /* [<][>][^][v][top][bottom][index][help] */
  38 {
  39         struct cli_credentials *cred = talloc(mem_ctx, struct cli_credentials);
  40         if (!cred) {
  41                 return cred;
  42         }
  43 
  44         cred->netlogon_creds = NULL;
  45         cred->machine_account_pending = false;
  46         cred->workstation_obtained = CRED_UNINITIALISED;
  47         cred->username_obtained = CRED_UNINITIALISED;
  48         cred->password_obtained = CRED_UNINITIALISED;
  49         cred->domain_obtained = CRED_UNINITIALISED;
  50         cred->realm_obtained = CRED_UNINITIALISED;
  51         cred->ccache_obtained = CRED_UNINITIALISED;
  52         cred->client_gss_creds_obtained = CRED_UNINITIALISED;
  53         cred->server_gss_creds_obtained = CRED_UNINITIALISED;
  54         cred->keytab_obtained = CRED_UNINITIALISED;
  55         cred->principal_obtained = CRED_UNINITIALISED;
  56 
  57         cred->ccache_threshold = CRED_UNINITIALISED;
  58         cred->client_gss_creds_threshold = CRED_UNINITIALISED;
  59 
  60         cred->old_password = NULL;
  61         cred->smb_krb5_context = NULL;
  62         cred->salt_principal = NULL;
  63         cred->machine_account = false;
  64 
  65         cred->bind_dn = NULL;
  66 
  67         cred->tries = 3;
  68         cred->callback_running = false;
  69 
  70         cli_credentials_set_kerberos_state(cred, CRED_AUTO_USE_KERBEROS);
  71         cli_credentials_set_gensec_features(cred, 0);
  72 
  73         return cred;
  74 }
  75 
  76 /**
  77  * Create a new anonymous credential
  78  * @param mem_ctx TALLOC_CTX parent for credentials structure 
  79  */
  80 _PUBLIC_ struct cli_credentials *cli_credentials_init_anon(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  81 {
  82         struct cli_credentials *anon_credentials;
  83 
  84         anon_credentials = cli_credentials_init(mem_ctx);
  85         cli_credentials_set_anonymous(anon_credentials);
  86 
  87         return anon_credentials;
  88 }
  89 
  90 _PUBLIC_ void cli_credentials_set_kerberos_state(struct cli_credentials *creds, 
     /* [<][>][^][v][top][bottom][index][help] */
  91                                         enum credentials_use_kerberos use_kerberos)
  92 {
  93         creds->use_kerberos = use_kerberos;
  94 }
  95 
  96 _PUBLIC_ enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds)
     /* [<][>][^][v][top][bottom][index][help] */
  97 {
  98         return creds->use_kerberos;
  99 }
 100 
 101 _PUBLIC_ void cli_credentials_set_gensec_features(struct cli_credentials *creds, uint32_t gensec_features)
     /* [<][>][^][v][top][bottom][index][help] */
 102 {
 103         creds->gensec_features = gensec_features;
 104 }
 105 
 106 _PUBLIC_ uint32_t cli_credentials_get_gensec_features(struct cli_credentials *creds)
     /* [<][>][^][v][top][bottom][index][help] */
 107 {
 108         return creds->gensec_features;
 109 }
 110 
 111 
 112 /**
 113  * Obtain the username for this credentials context.
 114  * @param cred credentials context
 115  * @retval The username set on this context.
 116  * @note Return value will never be NULL except by programmer error.
 117  */
 118 _PUBLIC_ const char *cli_credentials_get_username(struct cli_credentials *cred)
     /* [<][>][^][v][top][bottom][index][help] */
 119 {
 120         if (cred->machine_account_pending) {
 121                 cli_credentials_set_machine_account(cred, 
 122                                         cred->machine_account_pending_lp_ctx);
 123         }
 124 
 125         if (cred->username_obtained == CRED_CALLBACK && 
 126             !cred->callback_running) {
 127                 cred->callback_running = true;
 128                 cred->username = cred->username_cb(cred);
 129                 cred->callback_running = false;
 130                 cred->username_obtained = CRED_SPECIFIED;
 131                 cli_credentials_invalidate_ccache(cred, cred->username_obtained);
 132         }
 133 
 134         return cred->username;
 135 }
 136 
 137 _PUBLIC_ bool cli_credentials_set_username(struct cli_credentials *cred, 
     /* [<][>][^][v][top][bottom][index][help] */
 138                                   const char *val, enum credentials_obtained obtained)
 139 {
 140         if (obtained >= cred->username_obtained) {
 141                 cred->username = talloc_strdup(cred, val);
 142                 cred->username_obtained = obtained;
 143                 cli_credentials_invalidate_ccache(cred, cred->username_obtained);
 144                 return true;
 145         }
 146 
 147         return false;
 148 }
 149 
 150 bool cli_credentials_set_username_callback(struct cli_credentials *cred,
     /* [<][>][^][v][top][bottom][index][help] */
 151                                   const char *(*username_cb) (struct cli_credentials *))
 152 {
 153         if (cred->username_obtained < CRED_CALLBACK) {
 154                 cred->username_cb = username_cb;
 155                 cred->username_obtained = CRED_CALLBACK;
 156                 return true;
 157         }
 158 
 159         return false;
 160 }
 161 
 162 _PUBLIC_ bool cli_credentials_set_bind_dn(struct cli_credentials *cred, 
     /* [<][>][^][v][top][bottom][index][help] */
 163                                  const char *bind_dn)
 164 {
 165         cred->bind_dn = talloc_strdup(cred, bind_dn);
 166         return true;
 167 }
 168 
 169 /**
 170  * Obtain the BIND DN for this credentials context.
 171  * @param cred credentials context
 172  * @retval The username set on this context.
 173  * @note Return value will be NULL if not specified explictly
 174  */
 175 _PUBLIC_ const char *cli_credentials_get_bind_dn(struct cli_credentials *cred)
     /* [<][>][^][v][top][bottom][index][help] */
 176 {
 177         return cred->bind_dn;
 178 }
 179 
 180 
 181 /**
 182  * Obtain the client principal for this credentials context.
 183  * @param cred credentials context
 184  * @retval The username set on this context.
 185  * @note Return value will never be NULL except by programmer error.
 186  */
 187 _PUBLIC_ const char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 188 {
 189         if (cred->machine_account_pending) {
 190                 cli_credentials_set_machine_account(cred,
 191                                         cred->machine_account_pending_lp_ctx);
 192         }
 193 
 194         if (cred->principal_obtained == CRED_CALLBACK && 
 195             !cred->callback_running) {
 196                 cred->callback_running = true;
 197                 cred->principal = cred->principal_cb(cred);
 198                 cred->callback_running = false;
 199                 cred->principal_obtained = CRED_SPECIFIED;
 200                 cli_credentials_invalidate_ccache(cred, cred->principal_obtained);
 201         }
 202 
 203         if (cred->principal_obtained < cred->username_obtained) {
 204                 if (cred->domain_obtained > cred->realm_obtained) {
 205                         return talloc_asprintf(mem_ctx, "%s@%s", 
 206                                                cli_credentials_get_username(cred),
 207                                                cli_credentials_get_domain(cred));
 208                 } else {
 209                         return talloc_asprintf(mem_ctx, "%s@%s", 
 210                                                cli_credentials_get_username(cred),
 211                                                cli_credentials_get_realm(cred));
 212                 }
 213         }
 214         return talloc_reference(mem_ctx, cred->principal);
 215 }
 216 
 217 bool cli_credentials_set_principal(struct cli_credentials *cred, 
     /* [<][>][^][v][top][bottom][index][help] */
 218                                    const char *val, 
 219                                    enum credentials_obtained obtained)
 220 {
 221         if (obtained >= cred->principal_obtained) {
 222                 cred->principal = talloc_strdup(cred, val);
 223                 cred->principal_obtained = obtained;
 224                 cli_credentials_invalidate_ccache(cred, cred->principal_obtained);
 225                 return true;
 226         }
 227 
 228         return false;
 229 }
 230 
 231 /* Set a callback to get the principal.  This could be a popup dialog,
 232  * a terminal prompt or similar.  */
 233 bool cli_credentials_set_principal_callback(struct cli_credentials *cred,
     /* [<][>][^][v][top][bottom][index][help] */
 234                                   const char *(*principal_cb) (struct cli_credentials *))
 235 {
 236         if (cred->principal_obtained < CRED_CALLBACK) {
 237                 cred->principal_cb = principal_cb;
 238                 cred->principal_obtained = CRED_CALLBACK;
 239                 return true;
 240         }
 241 
 242         return false;
 243 }
 244 
 245 /* Some of our tools are 'anonymous by default'.  This is a single
 246  * function to determine if authentication has been explicitly
 247  * requested */
 248 
 249 _PUBLIC_ bool cli_credentials_authentication_requested(struct cli_credentials *cred) 
     /* [<][>][^][v][top][bottom][index][help] */
 250 {
 251         if (cred->bind_dn) {
 252                 return true;
 253         }
 254 
 255         if (cli_credentials_is_anonymous(cred)){
 256                 return false;
 257         }
 258 
 259         if (cred->principal_obtained >= CRED_SPECIFIED) {
 260                 return true;
 261         }
 262         if (cred->username_obtained >= CRED_SPECIFIED) {
 263                 return true;
 264         }
 265 
 266         if (cli_credentials_get_kerberos_state(cred) == CRED_MUST_USE_KERBEROS) {
 267                 return true;
 268         }
 269 
 270         return false;
 271 }
 272 
 273 /**
 274  * Obtain the password for this credentials context.
 275  * @param cred credentials context
 276  * @retval If set, the cleartext password, otherwise NULL
 277  */
 278 _PUBLIC_ const char *cli_credentials_get_password(struct cli_credentials *cred)
     /* [<][>][^][v][top][bottom][index][help] */
 279 {
 280         if (cred->machine_account_pending) {
 281                 cli_credentials_set_machine_account(cred,
 282                                                     cred->machine_account_pending_lp_ctx);
 283         }
 284 
 285         if (cred->password_obtained == CRED_CALLBACK && 
 286             !cred->callback_running) {
 287                 cred->callback_running = true;
 288                 cred->password = cred->password_cb(cred);
 289                 cred->callback_running = false;
 290                 cred->password_obtained = CRED_CALLBACK_RESULT;
 291                 cli_credentials_invalidate_ccache(cred, cred->password_obtained);
 292         }
 293 
 294         return cred->password;
 295 }
 296 
 297 /* Set a password on the credentials context, including an indication
 298  * of 'how' the password was obtained */
 299 
 300 _PUBLIC_ bool cli_credentials_set_password(struct cli_credentials *cred, 
     /* [<][>][^][v][top][bottom][index][help] */
 301                                   const char *val, 
 302                                   enum credentials_obtained obtained)
 303 {
 304         if (obtained >= cred->password_obtained) {
 305                 cred->password = talloc_strdup(cred, val);
 306                 cred->password_obtained = obtained;
 307                 cli_credentials_invalidate_ccache(cred, cred->password_obtained);
 308 
 309                 cred->nt_hash = NULL;
 310                 cred->lm_response = data_blob(NULL, 0);
 311                 cred->nt_response = data_blob(NULL, 0);
 312                 return true;
 313         }
 314 
 315         return false;
 316 }
 317 
 318 _PUBLIC_ bool cli_credentials_set_password_callback(struct cli_credentials *cred,
     /* [<][>][^][v][top][bottom][index][help] */
 319                                            const char *(*password_cb) (struct cli_credentials *))
 320 {
 321         if (cred->password_obtained < CRED_CALLBACK) {
 322                 cred->password_cb = password_cb;
 323                 cred->password_obtained = CRED_CALLBACK;
 324                 cli_credentials_invalidate_ccache(cred, cred->password_obtained);
 325                 return true;
 326         }
 327 
 328         return false;
 329 }
 330 
 331 /**
 332  * Obtain the 'old' password for this credentials context (used for join accounts).
 333  * @param cred credentials context
 334  * @retval If set, the cleartext password, otherwise NULL
 335  */
 336 const char *cli_credentials_get_old_password(struct cli_credentials *cred)
     /* [<][>][^][v][top][bottom][index][help] */
 337 {
 338         if (cred->machine_account_pending) {
 339                 cli_credentials_set_machine_account(cred,
 340                                                     cred->machine_account_pending_lp_ctx);
 341         }
 342 
 343         return cred->old_password;
 344 }
 345 
 346 bool cli_credentials_set_old_password(struct cli_credentials *cred, 
     /* [<][>][^][v][top][bottom][index][help] */
 347                                       const char *val, 
 348                                       enum credentials_obtained obtained)
 349 {
 350         cred->old_password = talloc_strdup(cred, val);
 351         return true;
 352 }
 353 
 354 /**
 355  * Obtain the password, in the form MD4(unicode(password)) for this credentials context.
 356  *
 357  * Sometimes we only have this much of the password, while the rest of
 358  * the time this call avoids calling E_md4hash themselves.
 359  *
 360  * @param cred credentials context
 361  * @retval If set, the cleartext password, otherwise NULL
 362  */
 363 _PUBLIC_ const struct samr_Password *cli_credentials_get_nt_hash(struct cli_credentials *cred, 
     /* [<][>][^][v][top][bottom][index][help] */
 364                                                         TALLOC_CTX *mem_ctx)
 365 {
 366         const char *password = cli_credentials_get_password(cred);
 367 
 368         if (password) {
 369                 struct samr_Password *nt_hash = talloc(mem_ctx, struct samr_Password);
 370                 if (!nt_hash) {
 371                         return NULL;
 372                 }
 373                 
 374                 E_md4hash(password, nt_hash->hash);    
 375 
 376                 return nt_hash;
 377         } else {
 378                 return cred->nt_hash;
 379         }
 380 }
 381 
 382 /**
 383  * Obtain the 'short' or 'NetBIOS' domain for this credentials context.
 384  * @param cred credentials context
 385  * @retval The domain set on this context. 
 386  * @note Return value will never be NULL except by programmer error.
 387  */
 388 _PUBLIC_ const char *cli_credentials_get_domain(struct cli_credentials *cred)
     /* [<][>][^][v][top][bottom][index][help] */
 389 {
 390         if (cred->machine_account_pending) {
 391                 cli_credentials_set_machine_account(cred,
 392                                                     cred->machine_account_pending_lp_ctx);
 393         }
 394 
 395         if (cred->domain_obtained == CRED_CALLBACK && 
 396             !cred->callback_running) {
 397                 cred->callback_running = true;
 398                 cred->domain = cred->domain_cb(cred);
 399                 cred->callback_running = false;
 400                 cred->domain_obtained = CRED_SPECIFIED;
 401                 cli_credentials_invalidate_ccache(cred, cred->domain_obtained);
 402         }
 403 
 404         return cred->domain;
 405 }
 406 
 407 
 408 _PUBLIC_ bool cli_credentials_set_domain(struct cli_credentials *cred, 
     /* [<][>][^][v][top][bottom][index][help] */
 409                                 const char *val, 
 410                                 enum credentials_obtained obtained)
 411 {
 412         if (obtained >= cred->domain_obtained) {
 413                 /* it is important that the domain be in upper case,
 414                  * particularly for the sensitive NTLMv2
 415                  * calculations */
 416                 cred->domain = strupper_talloc(cred, val);
 417                 cred->domain_obtained = obtained;
 418                 cli_credentials_invalidate_ccache(cred, cred->domain_obtained);
 419                 return true;
 420         }
 421 
 422         return false;
 423 }
 424 
 425 bool cli_credentials_set_domain_callback(struct cli_credentials *cred,
     /* [<][>][^][v][top][bottom][index][help] */
 426                                          const char *(*domain_cb) (struct cli_credentials *))
 427 {
 428         if (cred->domain_obtained < CRED_CALLBACK) {
 429                 cred->domain_cb = domain_cb;
 430                 cred->domain_obtained = CRED_CALLBACK;
 431                 return true;
 432         }
 433 
 434         return false;
 435 }
 436 
 437 /**
 438  * Obtain the Kerberos realm for this credentials context.
 439  * @param cred credentials context
 440  * @retval The realm set on this context. 
 441  * @note Return value will never be NULL except by programmer error.
 442  */
 443 _PUBLIC_ const char *cli_credentials_get_realm(struct cli_credentials *cred)
     /* [<][>][^][v][top][bottom][index][help] */
 444 {       
 445         if (cred->machine_account_pending) {
 446                 cli_credentials_set_machine_account(cred,
 447                                                     cred->machine_account_pending_lp_ctx);
 448         }
 449 
 450         if (cred->realm_obtained == CRED_CALLBACK && 
 451             !cred->callback_running) {
 452                 cred->callback_running = true;
 453                 cred->realm = cred->realm_cb(cred);
 454                 cred->callback_running = false;
 455                 cred->realm_obtained = CRED_SPECIFIED;
 456                 cli_credentials_invalidate_ccache(cred, cred->realm_obtained);
 457         }
 458 
 459         return cred->realm;
 460 }
 461 
 462 /**
 463  * Set the realm for this credentials context, and force it to
 464  * uppercase for the sainity of our local kerberos libraries 
 465  */
 466 _PUBLIC_ bool cli_credentials_set_realm(struct cli_credentials *cred, 
     /* [<][>][^][v][top][bottom][index][help] */
 467                                const char *val, 
 468                                enum credentials_obtained obtained)
 469 {
 470         if (obtained >= cred->realm_obtained) {
 471                 cred->realm = strupper_talloc(cred, val);
 472                 cred->realm_obtained = obtained;
 473                 cli_credentials_invalidate_ccache(cred, cred->realm_obtained);
 474                 return true;
 475         }
 476 
 477         return false;
 478 }
 479 
 480 bool cli_credentials_set_realm_callback(struct cli_credentials *cred,
     /* [<][>][^][v][top][bottom][index][help] */
 481                                         const char *(*realm_cb) (struct cli_credentials *))
 482 {
 483         if (cred->realm_obtained < CRED_CALLBACK) {
 484                 cred->realm_cb = realm_cb;
 485                 cred->realm_obtained = CRED_CALLBACK;
 486                 return true;
 487         }
 488 
 489         return false;
 490 }
 491 
 492 /**
 493  * Obtain the 'short' or 'NetBIOS' workstation name for this credentials context.
 494  *
 495  * @param cred credentials context
 496  * @retval The workstation name set on this context. 
 497  * @note Return value will never be NULL except by programmer error.
 498  */
 499 _PUBLIC_ const char *cli_credentials_get_workstation(struct cli_credentials *cred)
     /* [<][>][^][v][top][bottom][index][help] */
 500 {
 501         if (cred->workstation_obtained == CRED_CALLBACK && 
 502             !cred->callback_running) {
 503                 cred->callback_running = true;
 504                 cred->workstation = cred->workstation_cb(cred);
 505                 cred->callback_running = false;
 506                 cred->workstation_obtained = CRED_SPECIFIED;
 507         }
 508 
 509         return cred->workstation;
 510 }
 511 
 512 _PUBLIC_ bool cli_credentials_set_workstation(struct cli_credentials *cred, 
     /* [<][>][^][v][top][bottom][index][help] */
 513                                      const char *val, 
 514                                      enum credentials_obtained obtained)
 515 {
 516         if (obtained >= cred->workstation_obtained) {
 517                 cred->workstation = talloc_strdup(cred, val);
 518                 cred->workstation_obtained = obtained;
 519                 return true;
 520         }
 521 
 522         return false;
 523 }
 524 
 525 bool cli_credentials_set_workstation_callback(struct cli_credentials *cred,
     /* [<][>][^][v][top][bottom][index][help] */
 526                                               const char *(*workstation_cb) (struct cli_credentials *))
 527 {
 528         if (cred->workstation_obtained < CRED_CALLBACK) {
 529                 cred->workstation_cb = workstation_cb;
 530                 cred->workstation_obtained = CRED_CALLBACK;
 531                 return true;
 532         }
 533 
 534         return false;
 535 }
 536 
 537 /**
 538  * Given a string, typically obtained from a -U argument, parse it into domain, username, realm and password fields
 539  *
 540  * The format accepted is [domain\\]user[%password] or user[@realm][%password]
 541  *
 542  * @param credentials Credentials structure on which to set the password
 543  * @param data the string containing the username, password etc
 544  * @param obtained This enum describes how 'specified' this password is
 545  */
 546 
 547 _PUBLIC_ void cli_credentials_parse_string(struct cli_credentials *credentials, const char *data, enum credentials_obtained obtained)
     /* [<][>][^][v][top][bottom][index][help] */
 548 {
 549         char *uname, *p;
 550 
 551         if (strcmp("%",data) == 0) {
 552                 cli_credentials_set_anonymous(credentials);
 553                 return;
 554         }
 555 
 556         uname = talloc_strdup(credentials, data); 
 557         if ((p = strchr_m(uname,'%'))) {
 558                 *p = 0;
 559                 cli_credentials_set_password(credentials, p+1, obtained);
 560         }
 561 
 562         if ((p = strchr_m(uname,'@'))) {
 563                 cli_credentials_set_principal(credentials, uname, obtained);
 564                 *p = 0;
 565                 cli_credentials_set_realm(credentials, p+1, obtained);
 566                 return;
 567         } else if ((p = strchr_m(uname,'\\')) || (p = strchr_m(uname, '/'))) {
 568                 *p = 0;
 569                 cli_credentials_set_domain(credentials, uname, obtained);
 570                 uname = p+1;
 571         }
 572         cli_credentials_set_username(credentials, uname, obtained);
 573 }
 574 
 575 /**
 576  * Given a a credentials structure, print it as a string
 577  *
 578  * The format output is [domain\\]user[%password] or user[@realm][%password]
 579  *
 580  * @param credentials Credentials structure on which to set the password
 581  * @param mem_ctx The memory context to place the result on
 582  */
 583 
 584 _PUBLIC_ const char *cli_credentials_get_unparsed_name(struct cli_credentials *credentials, TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 585 {
 586         const char *bind_dn = cli_credentials_get_bind_dn(credentials);
 587         const char *domain;
 588         const char *username;
 589         const char *name;
 590 
 591         if (bind_dn) {
 592                 name = talloc_reference(mem_ctx, bind_dn);
 593         } else {
 594                 cli_credentials_get_ntlm_username_domain(credentials, mem_ctx, &username, &domain);
 595                 if (domain && domain[0]) {
 596                         name = talloc_asprintf(mem_ctx, "%s\\%s", 
 597                                                domain, username);
 598                 } else {
 599                         name = talloc_asprintf(mem_ctx, "%s", 
 600                                                username);
 601                 }
 602         }
 603         return name;
 604 }
 605 
 606 /**
 607  * Specifies default values for domain, workstation and realm
 608  * from the smb.conf configuration file
 609  *
 610  * @param cred Credentials structure to fill in
 611  */
 612 _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred, 
     /* [<][>][^][v][top][bottom][index][help] */
 613                               struct loadparm_context *lp_ctx)
 614 {
 615         cli_credentials_set_username(cred, "", CRED_UNINITIALISED);
 616         cli_credentials_set_domain(cred, lp_workgroup(lp_ctx), CRED_UNINITIALISED);
 617         cli_credentials_set_workstation(cred, lp_netbios_name(lp_ctx), CRED_UNINITIALISED);
 618         cli_credentials_set_realm(cred, lp_realm(lp_ctx), CRED_UNINITIALISED);
 619 }
 620 
 621 /**
 622  * Guess defaults for credentials from environment variables, 
 623  * and from the configuration file
 624  * 
 625  * @param cred Credentials structure to fill in
 626  */
 627 _PUBLIC_ void cli_credentials_guess(struct cli_credentials *cred,
     /* [<][>][^][v][top][bottom][index][help] */
 628                            struct loadparm_context *lp_ctx)
 629 {
 630         char *p;
 631 
 632         if (lp_ctx != NULL) {
 633                 cli_credentials_set_conf(cred, lp_ctx);
 634         }
 635         
 636         if (getenv("LOGNAME")) {
 637                 cli_credentials_set_username(cred, getenv("LOGNAME"), CRED_GUESS_ENV);
 638         }
 639 
 640         if (getenv("USER")) {
 641                 cli_credentials_parse_string(cred, getenv("USER"), CRED_GUESS_ENV);
 642                 if ((p = strchr_m(getenv("USER"),'%'))) {
 643                         memset(p,0,strlen(cred->password));
 644                 }
 645         }
 646 
 647         if (getenv("PASSWD")) {
 648                 cli_credentials_set_password(cred, getenv("PASSWD"), CRED_GUESS_ENV);
 649         }
 650 
 651         if (getenv("PASSWD_FD")) {
 652                 cli_credentials_parse_password_fd(cred, atoi(getenv("PASSWD_FD")), 
 653                                                   CRED_GUESS_FILE);
 654         }
 655         
 656         p = getenv("PASSWD_FILE");
 657         if (p && p[0]) {
 658                 cli_credentials_parse_password_file(cred, p, CRED_GUESS_FILE);
 659         }
 660         
 661         if (cli_credentials_get_kerberos_state(cred) != CRED_DONT_USE_KERBEROS) {
 662                 cli_credentials_set_ccache(cred, event_context_find(cred), lp_ctx, NULL, CRED_GUESS_FILE);
 663         }
 664 }
 665 
 666 /**
 667  * Attach NETLOGON credentials for use with SCHANNEL
 668  */
 669 
 670 _PUBLIC_ void cli_credentials_set_netlogon_creds(struct cli_credentials *cred, 
     /* [<][>][^][v][top][bottom][index][help] */
 671                                         struct creds_CredentialState *netlogon_creds)
 672 {
 673         cred->netlogon_creds = talloc_reference(cred, netlogon_creds);
 674 }
 675 
 676 /**
 677  * Return attached NETLOGON credentials 
 678  */
 679 
 680 struct creds_CredentialState *cli_credentials_get_netlogon_creds(struct cli_credentials *cred)
     /* [<][>][^][v][top][bottom][index][help] */
 681 {
 682         return cred->netlogon_creds;
 683 }
 684 
 685 /** 
 686  * Set NETLOGON secure channel type
 687  */
 688 
 689 _PUBLIC_ void cli_credentials_set_secure_channel_type(struct cli_credentials *cred,
     /* [<][>][^][v][top][bottom][index][help] */
 690                                              enum netr_SchannelType secure_channel_type)
 691 {
 692         cred->secure_channel_type = secure_channel_type;
 693 }
 694 
 695 /**
 696  * Return NETLOGON secure chanel type
 697  */
 698 
 699 _PUBLIC_ enum netr_SchannelType cli_credentials_get_secure_channel_type(struct cli_credentials *cred)
     /* [<][>][^][v][top][bottom][index][help] */
 700 {
 701         return cred->secure_channel_type;
 702 }
 703 
 704 /**
 705  * Fill in a credentials structure as the anonymous user
 706  */
 707 _PUBLIC_ void cli_credentials_set_anonymous(struct cli_credentials *cred) 
     /* [<][>][^][v][top][bottom][index][help] */
 708 {
 709         cli_credentials_set_username(cred, "", CRED_SPECIFIED);
 710         cli_credentials_set_domain(cred, "", CRED_SPECIFIED);
 711         cli_credentials_set_password(cred, NULL, CRED_SPECIFIED);
 712         cli_credentials_set_realm(cred, NULL, CRED_SPECIFIED);
 713         cli_credentials_set_workstation(cred, "", CRED_UNINITIALISED);
 714 }
 715 
 716 /**
 717  * Describe a credentials context as anonymous or authenticated
 718  * @retval true if anonymous, false if a username is specified
 719  */
 720 
 721 _PUBLIC_ bool cli_credentials_is_anonymous(struct cli_credentials *cred)
     /* [<][>][^][v][top][bottom][index][help] */
 722 {
 723         const char *username;
 724         
 725         if (cred->machine_account_pending) {
 726                 cli_credentials_set_machine_account(cred,
 727                                                     cred->machine_account_pending_lp_ctx);
 728         }
 729 
 730         username = cli_credentials_get_username(cred);
 731         
 732         /* Yes, it is deliberate that we die if we have a NULL pointer
 733          * here - anonymous is "", not NULL, which is 'never specified,
 734          * never guessed', ie programmer bug */
 735         if (!username[0]) {
 736                 return true;
 737         }
 738 
 739         return false;
 740 }
 741 
 742 /**
 743  * Mark the current password for a credentials struct as wrong. This will 
 744  * cause the password to be prompted again (if a callback is set).
 745  *
 746  * This will decrement the number of times the password can be tried.
 747  *
 748  * @retval whether the credentials struct is finished
 749  */
 750 _PUBLIC_ bool cli_credentials_wrong_password(struct cli_credentials *cred)
     /* [<][>][^][v][top][bottom][index][help] */
 751 {
 752         if (cred->password_obtained != CRED_CALLBACK_RESULT) {
 753                 return false;
 754         }
 755         
 756         cred->password_obtained = CRED_CALLBACK;
 757 
 758         cred->tries--;
 759 
 760         return (cred->tries > 0);
 761 }

/* [<][>][^][v][top][bottom][index][help] */