cifs.upcall: do a brute-force search for KRB5 credcache
[kai/samba.git] / nsswitch / pam_winbind.c
index d049bdb1e7d538bce21ac1628be6282c0502f337..4e84574d258b3a9db57fc4efcf2b108265810e3d 100644 (file)
@@ -11,6 +11,8 @@
 */
 
 #include "pam_winbind.h"
+#define CONST_DISCARD(type,ptr) ((type)(void *)ptr)
+
 
 static int wbc_error_to_pam_error(wbcErr status)
 {
@@ -410,49 +412,51 @@ static int _pam_parse(const pam_handle_t *pamh,
                config_file = PAM_WINBIND_CONFIG_FILE;
        }
 
-       d = iniparser_load(config_file);
+       d = iniparser_load(CONST_DISCARD(char *, config_file));
        if (d == NULL) {
                goto config_from_pam;
        }
 
-       if (iniparser_getboolean(d, "global:debug", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:debug"), false)) {
                ctrl |= WINBIND_DEBUG_ARG;
        }
 
-       if (iniparser_getboolean(d, "global:debug_state", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:debug_state"), false)) {
                ctrl |= WINBIND_DEBUG_STATE;
        }
 
-       if (iniparser_getboolean(d, "global:cached_login", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:cached_login"), false)) {
                ctrl |= WINBIND_CACHED_LOGIN;
        }
 
-       if (iniparser_getboolean(d, "global:krb5_auth", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:krb5_auth"), false)) {
                ctrl |= WINBIND_KRB5_AUTH;
        }
 
-       if (iniparser_getboolean(d, "global:silent", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:silent"), false)) {
                ctrl |= WINBIND_SILENT;
        }
 
-       if (iniparser_getstr(d, "global:krb5_ccache_type") != NULL) {
+       if (iniparser_getstr(d, CONST_DISCARD(char *, "global:krb5_ccache_type")) != NULL) {
                ctrl |= WINBIND_KRB5_CCACHE_TYPE;
        }
 
-       if ((iniparser_getstr(d, "global:require-membership-of") != NULL) ||
-           (iniparser_getstr(d, "global:require_membership_of") != NULL)) {
+       if ((iniparser_getstr(d, CONST_DISCARD(char *, "global:require-membership-of"))
+            != NULL) ||
+           (iniparser_getstr(d, CONST_DISCARD(char *, "global:require_membership_of"))
+            != NULL)) {
                ctrl |= WINBIND_REQUIRED_MEMBERSHIP;
        }
 
-       if (iniparser_getboolean(d, "global:try_first_pass", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:try_first_pass"), false)) {
                ctrl |= WINBIND_TRY_FIRST_PASS_ARG;
        }
 
-       if (iniparser_getint(d, "global:warn_pwd_expire", 0)) {
+       if (iniparser_getint(d, CONST_DISCARD(char *, "global:warn_pwd_expire"), 0)) {
                ctrl |= WINBIND_WARN_PWD_EXPIRE;
        }
 
-       if (iniparser_getboolean(d, "global:mkhomedir", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:mkhomedir"), false)) {
                ctrl |= WINBIND_MKHOMEDIR;
        }
 
@@ -914,7 +918,8 @@ static void _pam_warn_password_expiry(struct pwb_context *ctx,
        /* now check for the global password policy */
        /* good catch from Ralf Haferkamp: an expiry of "never" is translated
         * to -1 */
-       if (policy->expire <= 0) {
+       if ((policy->expire == (int64_t)-1) ||
+           (policy->expire == 0)) {
                return;
        }
 
@@ -2283,6 +2288,7 @@ static char* winbind_upn_to_username(struct pwb_context *ctx,
        enum wbcSidType type;
        char *domain;
        char *name;
+       char *p;
 
        /* This cannot work when the winbind separator = @ */
 
@@ -2291,9 +2297,18 @@ static char* winbind_upn_to_username(struct pwb_context *ctx,
                return NULL;
        }
 
+       name = talloc_strdup(ctx, upn);
+       if (!name) {
+               return NULL;
+       }
+       if ((p = strchr(name, '@')) != NULL) {
+               *p = 0;
+               domain = p + 1;
+       }
+
        /* Convert the UPN to a SID */
 
-       wbc_status = wbcLookupName("", upn, &sid, &type);
+       wbc_status = wbcLookupName(domain, name, &sid, &type);
        if (!WBC_ERROR_IS_OK(wbc_status)) {
                return NULL;
        }
@@ -2318,6 +2333,8 @@ static int _pam_delete_cred(pam_handle_t *pamh, int flags,
        const char *user;
        wbcErr wbc_status = WBC_ERR_SUCCESS;
 
+       ZERO_STRUCT(logoff);
+
        retval = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
        if (retval) {
                goto out;
@@ -2365,8 +2382,6 @@ static int _pam_delete_cred(pam_handle_t *pamh, int flags,
                wbc_flags = WBFLAG_PAM_KRB5 |
                        WBFLAG_PAM_CONTACT_TRUSTDOM;
 
-               ZERO_STRUCT(logoff);
-
                logoff.username         = user;
 
                if (ccname) {
@@ -2406,6 +2421,7 @@ static int _pam_delete_cred(pam_handle_t *pamh, int flags,
                                                     user, "wbcLogoffUser");
                wbcFreeMemory(error);
                wbcFreeMemory(logoff.blobs);
+               logoff.blobs = NULL;
 
                if (!WBC_ERROR_IS_OK(wbc_status)) {
                        _pam_log(ctx, LOG_INFO,
@@ -2428,7 +2444,7 @@ out:
         * Delete the krb5 ccname variable from the PAM environment
         * if it was set by winbind.
         */
-       if (ctx->ctrl & WINBIND_KRB5_AUTH) {
+       if ((ctx->ctrl & WINBIND_KRB5_AUTH) && pam_getenv(pamh, "KRB5CCNAME")) {
                pam_putenv(pamh, "KRB5CCNAME");
        }