libreplace: Fix the build on Solaris
[sfrench/samba-autobuild/.git] / nsswitch / pam_winbind.c
index f7637e7ea70fca21e6351566d2a72677ed43d063..a2d9f3bde9e9e0ad482df6b8f22c314f1919b27a 100644 (file)
 
 #include "pam_winbind.h"
 
+enum pam_winbind_request_type 
+{
+       PAM_WINBIND_AUTHENTICATE,
+       PAM_WINBIND_SETCRED,
+       PAM_WINBIND_ACCT_MGMT,
+       PAM_WINBIND_OPEN_SESSION,
+       PAM_WINBIND_CLOSE_SESSION,
+       PAM_WINBIND_CHAUTHTOK,
+       PAM_WINBIND_CLEANUP
+};
+
 static int wbc_error_to_pam_error(wbcErr status)
 {
        switch (status) {
@@ -138,7 +149,7 @@ static const char *_pam_error_code_str(int err)
 #define _PAM_LOG_FUNCTION_LEAVE(function, ctx, retval) \
        do { \
                _pam_log_debug(ctx, LOG_DEBUG, "[pamh: %p] LEAVE: " \
-                              function " returning %d (%s)", ctx->pamh, retval, \
+                              function " returning %d (%s)", ctx ? ctx->pamh : NULL, retval, \
                               _pam_error_code_str(retval)); \
                _pam_log_state(ctx); \
        } while (0)
@@ -162,25 +173,6 @@ static inline void textdomain_init(void)
 #endif
 
 
-/*
- * Work around the pam API that has functions with void ** as parameters
- * These lead to strict aliasing warnings with gcc.
- */
-static int _pam_get_item(const pam_handle_t *pamh,
-                        int item_type,
-                        const void *_item)
-{
-       const void **item = (const void **)_item;
-       return pam_get_item(pamh, item_type, item);
-}
-static int _pam_get_data(const pam_handle_t *pamh,
-                        const char *module_data_name,
-                        const void *_data)
-{
-       const void **data = (const void **)_data;
-       return pam_get_data(pamh, module_data_name, data);
-}
-
 /* some syslogging */
 
 #ifdef HAVE_PAM_VSYSLOG
@@ -200,7 +192,7 @@ static void _pam_log_int(const pam_handle_t *pamh,
        char *format2 = NULL;
        const char *service;
 
-       _pam_get_item(pamh, PAM_SERVICE, &service);
+       pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
 
        format2 = (char *)malloc(strlen(MODULE_NAME)+strlen(format)+strlen(service)+5);
        if (format2 == NULL) {
@@ -278,7 +270,7 @@ static void _pam_log_debug(struct pwb_context *r, int err, const char *format, .
 {
        va_list args;
 
-       if (!_pam_log_is_debug_enabled(r->ctrl)) {
+       if (!r || !_pam_log_is_debug_enabled(r->ctrl)) {
                return;
        }
 
@@ -347,10 +339,29 @@ static void _pam_log_state_datum(struct pwb_context *ctx,
 #define _PAM_LOG_STATE_ITEM_PASSWORD(ctx, item_type) \
        _pam_log_state_datum(ctx, item_type, #item_type, \
                             _LOG_PASSWORD_AS_STRING)
+/*
+ * wrapper to preserve old behaviour of iniparser which ignored
+ * key values that had no value assigned like
+ *    key =
+ * for a key like above newer iniparser will return a zero-length
+ * string, previously iniparser would return NULL
+ *
+ * JRA: For compatibility, tiniparser behaves like iniparser.
+ */
+static const char *tiniparser_getstring_nonempty(struct tiniparser_dictionary *d,
+                       const char *key,
+                       const char *def)
+{
+       const char *ret = tiniparser_getstring(d, key, def);
+       if (ret && strlen(ret) == 0) {
+               ret = NULL;
+       }
+       return ret;
+}
 
 static void _pam_log_state(struct pwb_context *ctx)
 {
-       if (!_pam_log_is_debug_state_enabled(ctx->ctrl)) {
+       if (!ctx || !_pam_log_is_debug_state_enabled(ctx->ctrl)) {
                return;
        }
 
@@ -386,13 +397,14 @@ static int _pam_parse(const pam_handle_t *pamh,
                      int flags,
                      int argc,
                      const char **argv,
-                     dictionary **result_d)
+                     enum pam_winbind_request_type type,
+                     struct tiniparser_dictionary **result_d)
 {
        int ctrl = 0;
        const char *config_file = NULL;
        int i;
        const char **v;
-       dictionary *d = NULL;
+       struct tiniparser_dictionary *d = NULL;
 
        if (flags & PAM_SILENT) {
                ctrl |= WINBIND_SILENT;
@@ -410,51 +422,51 @@ static int _pam_parse(const pam_handle_t *pamh,
                config_file = PAM_WINBIND_CONFIG_FILE;
        }
 
-       d = iniparser_load(discard_const_p(char, config_file));
+       d = tiniparser_load(config_file);
        if (d == NULL) {
                goto config_from_pam;
        }
 
-       if (iniparser_getboolean(d, discard_const_p(char, "global:debug"), false)) {
+       if (tiniparser_getboolean(d, "global:debug", false)) {
                ctrl |= WINBIND_DEBUG_ARG;
        }
 
-       if (iniparser_getboolean(d, discard_const_p(char, "global:debug_state"), false)) {
+       if (tiniparser_getboolean(d, "global:debug_state", false)) {
                ctrl |= WINBIND_DEBUG_STATE;
        }
 
-       if (iniparser_getboolean(d, discard_const_p(char, "global:cached_login"), false)) {
+       if (tiniparser_getboolean(d, "global:cached_login", false)) {
                ctrl |= WINBIND_CACHED_LOGIN;
        }
 
-       if (iniparser_getboolean(d, discard_const_p(char, "global:krb5_auth"), false)) {
+       if (tiniparser_getboolean(d, "global:krb5_auth", false)) {
                ctrl |= WINBIND_KRB5_AUTH;
        }
 
-       if (iniparser_getboolean(d, discard_const_p(char, "global:silent"), false)) {
+       if (tiniparser_getboolean(d, "global:silent", false)) {
                ctrl |= WINBIND_SILENT;
        }
 
-       if (iniparser_getstr(d, discard_const_p(char, "global:krb5_ccache_type")) != NULL) {
+       if (tiniparser_getstring_nonempty(d, "global:krb5_ccache_type", NULL) != NULL) {
                ctrl |= WINBIND_KRB5_CCACHE_TYPE;
        }
 
-       if ((iniparser_getstr(d, discard_const_p(char, "global:require-membership-of"))
+       if ((tiniparser_getstring_nonempty(d, "global:require-membership-of", NULL)
             != NULL) ||
-           (iniparser_getstr(d, discard_const_p(char, "global:require_membership_of"))
+           (tiniparser_getstring_nonempty(d, "global:require_membership_of", NULL)
             != NULL)) {
                ctrl |= WINBIND_REQUIRED_MEMBERSHIP;
        }
 
-       if (iniparser_getboolean(d, discard_const_p(char, "global:try_first_pass"), false)) {
+       if (tiniparser_getboolean(d, "global:try_first_pass", false)) {
                ctrl |= WINBIND_TRY_FIRST_PASS_ARG;
        }
 
-       if (iniparser_getint(d, discard_const_p(char, "global:warn_pwd_expire"), 0)) {
+       if (tiniparser_getint(d, "global:warn_pwd_expire", 0)) {
                ctrl |= WINBIND_WARN_PWD_EXPIRE;
        }
 
-       if (iniparser_getboolean(d, discard_const_p(char, "global:mkhomedir"), false)) {
+       if (tiniparser_getboolean(d, "global:mkhomedir", false)) {
                ctrl |= WINBIND_MKHOMEDIR;
        }
 
@@ -477,11 +489,15 @@ config_from_pam:
                        ctrl |= WINBIND_TRY_FIRST_PASS_ARG;
                else if (!strcasecmp(*v, "unknown_ok"))
                        ctrl |= WINBIND_UNKNOWN_OK_ARG;
-               else if (!strncasecmp(*v, "require_membership_of",
-                                     strlen("require_membership_of")))
+               else if ((type == PAM_WINBIND_AUTHENTICATE
+                         || type == PAM_WINBIND_SETCRED) 
+                        && !strncasecmp(*v, "require_membership_of",
+                                        strlen("require_membership_of")))
                        ctrl |= WINBIND_REQUIRED_MEMBERSHIP;
-               else if (!strncasecmp(*v, "require-membership-of",
-                                     strlen("require-membership-of")))
+               else if ((type == PAM_WINBIND_AUTHENTICATE 
+                         || type == PAM_WINBIND_SETCRED) 
+                        && !strncasecmp(*v, "require-membership-of",
+                                        strlen("require-membership-of")))
                        ctrl |= WINBIND_REQUIRED_MEMBERSHIP;
                else if (!strcasecmp(*v, "krb5_auth"))
                        ctrl |= WINBIND_KRB5_AUTH;
@@ -492,7 +508,10 @@ config_from_pam:
                        ctrl |= WINBIND_CACHED_LOGIN;
                else if (!strcasecmp(*v, "mkhomedir"))
                        ctrl |= WINBIND_MKHOMEDIR;
-               else {
+               else if (!strncasecmp(*v, "warn_pwd_expire",
+                       strlen("warn_pwd_expire")))
+                       ctrl |= WINBIND_WARN_PWD_EXPIRE;
+               else if (type != PAM_WINBIND_CLEANUP) {
                        __pam_log(pamh, ctrl, LOG_ERR,
                                 "pam_parse: unknown option: %s", *v);
                        return -1;
@@ -504,7 +523,7 @@ config_from_pam:
                *result_d = d;
        } else {
                if (d) {
-                       iniparser_freedict(d);
+                       tiniparser_freedict(d);
                }
        }
 
@@ -518,7 +537,7 @@ static int _pam_winbind_free_context(struct pwb_context *ctx)
        }
 
        if (ctx->dict) {
-               iniparser_freedict(ctx->dict);
+               tiniparser_freedict(ctx->dict);
        }
 
        return 0;
@@ -528,6 +547,7 @@ static int _pam_winbind_init_context(pam_handle_t *pamh,
                                     int flags,
                                     int argc,
                                     const char **argv,
+                                    enum pam_winbind_request_type type,
                                     struct pwb_context **ctx_p)
 {
        struct pwb_context *r = NULL;
@@ -536,7 +556,7 @@ static int _pam_winbind_init_context(pam_handle_t *pamh,
        textdomain_init();
 #endif
 
-       r = TALLOC_ZERO_P(NULL, struct pwb_context);
+       r = talloc_zero(NULL, struct pwb_context);
        if (!r) {
                return PAM_BUF_ERR;
        }
@@ -547,7 +567,7 @@ static int _pam_winbind_init_context(pam_handle_t *pamh,
        r->flags = flags;
        r->argc = argc;
        r->argv = argv;
-       r->ctrl = _pam_parse(pamh, flags, argc, argv, &r->dict);
+       r->ctrl = _pam_parse(pamh, flags, argc, argv, type, &r->dict);
        if (r->ctrl == -1) {
                TALLOC_FREE(r);
                return PAM_SYSTEM_ERR;
@@ -562,7 +582,7 @@ static void _pam_winbind_cleanup_func(pam_handle_t *pamh,
                                      void *data,
                                      int error_status)
 {
-       int ctrl = _pam_parse(pamh, 0, 0, NULL, NULL);
+       int ctrl = _pam_parse(pamh, 0, 0, NULL, PAM_WINBIND_CLEANUP, NULL);
        if (_pam_log_is_debug_state_enabled(ctrl)) {
                __pam_log_debug(pamh, ctrl, LOG_DEBUG,
                               "[pamh: %p] CLEAN: cleaning up PAM data %p "
@@ -643,10 +663,10 @@ static int converse(const pam_handle_t *pamh,
        int retval;
        struct pam_conv *conv;
 
-       retval = _pam_get_item(pamh, PAM_CONV, &conv);
+       retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
        if (retval == PAM_SUCCESS) {
                retval = conv->conv(nargs,
-                                   (const struct pam_message **)message,
+                                   discard_const_p(const struct pam_message *, message),
                                    response, conv->appdata_ptr);
        }
 
@@ -810,13 +830,11 @@ static bool _pam_winbind_change_pwd(struct pwb_context *ctx)
 {
        struct pam_message msg, *pmsg;
        struct pam_response *resp = NULL;
-       const char *prompt;
        int ret;
        bool retval = false;
-       prompt = _("Do you want to change your password now?");
        pmsg = &msg;
        msg.msg_style = PAM_RADIO_TYPE;
-       msg.msg = prompt;
+       msg.msg = _("Do you want to change your password now?");
        ret = converse(ctx->pamh, 1, &pmsg, &resp);
        if (resp == NULL) {
                if (ret == PAM_SUCCESS) {
@@ -829,7 +847,7 @@ static bool _pam_winbind_change_pwd(struct pwb_context *ctx)
        }
        _pam_log(ctx, LOG_CRIT, "Received [%s] reply from application.\n", resp->resp);
 
-       if (strcasecmp(resp->resp, "yes") == 0) {
+       if ((resp->resp != NULL) && (strcasecmp(resp->resp, "yes") == 0)) {
                retval = true;
        }
 
@@ -1047,15 +1065,9 @@ static bool safe_append_string(char *dest,
                               const char *src,
                               int dest_buffer_size)
 {
-       int dest_length = strlen(dest);
-       int src_length = strlen(src);
-
-       if (dest_length + src_length + 1 > dest_buffer_size) {
-               return false;
-       }
-
-       memcpy(dest + dest_length, src, src_length + 1);
-       return true;
+       size_t len;
+       len = strlcat(dest, src, dest_buffer_size);
+       return (len < dest_buffer_size);
 }
 
 /**
@@ -1182,6 +1194,12 @@ static bool winbind_name_list_to_sid_string_list(struct pwb_context *ctx,
                _make_remark_format(ctx, PAM_TEXT_INFO, _("Cannot convert group %s "
                                "to sid, please contact your administrator to see "
                                "if group %s is valid."), search_location, search_location);
+
+               /* If no valid groups were converted we should fail outright */
+               if (name_list != NULL && strlen(sid_list_buffer) == 0) {
+                       result = false;
+                       goto out;
+               }
                /*
                 * The lookup of the last name failed..
                 * It results in require_member_of_sid ends with ','
@@ -1212,7 +1230,7 @@ out:
 static void _pam_setup_krb5_env(struct pwb_context *ctx,
                                struct wbcLogonUserInfo *info)
 {
-       char var[PATH_MAX];
+       char *var = NULL;
        int ret;
        uint32_t i;
        const char *krb5ccname = NULL;
@@ -1239,7 +1257,7 @@ static void _pam_setup_krb5_env(struct pwb_context *ctx,
        _pam_log_debug(ctx, LOG_DEBUG,
                       "request returned KRB5CCNAME: %s", krb5ccname);
 
-       if (snprintf(var, sizeof(var), "KRB5CCNAME=%s", krb5ccname) == -1) {
+       if (asprintf(&var, "KRB5CCNAME=%s", krb5ccname) == -1) {
                return;
        }
 
@@ -1249,6 +1267,7 @@ static void _pam_setup_krb5_env(struct pwb_context *ctx,
                         "failed to set KRB5CCNAME to %s: %s",
                         var, pam_strerror(ctx->pamh, ret));
        }
+       free(var);
 }
 
 /**
@@ -1943,7 +1962,7 @@ static int winbind_chauthtok_request(struct pwb_context *ctx,
        }
 
        params.account_name             = user;
-       params.level                    = WBC_AUTH_USER_LEVEL_PLAIN;
+       params.level                    = WBC_CHANGE_PASSWORD_LEVEL_PLAIN;
        params.old_password.plaintext   = oldpass;
        params.new_password.plaintext   = newpass;
        params.flags                    = flags;
@@ -1982,7 +2001,7 @@ static int winbind_chauthtok_request(struct pwb_context *ctx,
                }
 
                /* FIXME: avoid to send multiple PAM messages after another */
-               switch (reject_reason) {
+               switch ((int)reject_reason) {
                        case -1:
                                break;
                        case WBC_PWD_CHANGE_NO_ERROR:
@@ -2061,6 +2080,9 @@ static int valid_user(struct pwb_context *ctx,
 
        switch (wbc_status) {
                case WBC_ERR_UNKNOWN_USER:
+               /* match other insane libwbclient return codes */
+               case WBC_ERR_WINBIND_NOT_AVAILABLE:
+               case WBC_ERR_DOMAIN_NOT_FOUND:
                        return 1;
                case WBC_ERR_SUCCESS:
                        return 0;
@@ -2117,7 +2139,9 @@ static int _winbind_read_password(struct pwb_context *ctx,
 
        if (on(WINBIND_TRY_FIRST_PASS_ARG, ctrl) ||
            on(WINBIND_USE_FIRST_PASS_ARG, ctrl)) {
-               retval = _pam_get_item(ctx->pamh, authtok_flag, &item);
+               retval = pam_get_item(ctx->pamh,
+                                     authtok_flag,
+                                     (const void **) &item);
                if (retval != PAM_SUCCESS) {
                        /* very strange. */
                        _pam_log(ctx, LOG_ALERT,
@@ -2225,7 +2249,7 @@ static int _winbind_read_password(struct pwb_context *ctx,
        retval = pam_set_item(ctx->pamh, authtok_flag, token);
        _pam_delete(token);     /* clean it up */
        if (retval != PAM_SUCCESS ||
-           (retval = _pam_get_item(ctx->pamh, authtok_flag, &item)) != PAM_SUCCESS) {
+           (retval = pam_get_item(ctx->pamh, authtok_flag, (const void **) &item)) != PAM_SUCCESS) {
 
                _pam_log(ctx, LOG_CRIT, "error manipulating password");
                return retval;
@@ -2275,7 +2299,7 @@ static const char *get_conf_item_string(struct pwb_context *ctx,
                        goto out;
                }
 
-               parm_opt = iniparser_getstr(ctx->dict, key);
+               parm_opt = tiniparser_getstring_nonempty(ctx->dict, key, NULL);
                TALLOC_FREE(key);
 
                _pam_log_debug(ctx, LOG_INFO, "CONFIG file: %s '%s'\n",
@@ -2323,7 +2347,7 @@ static int get_config_item_int(struct pwb_context *ctx,
                        goto out;
                }
 
-               parm_opt = iniparser_getint(ctx->dict, key, -1);
+               parm_opt = tiniparser_getint(ctx->dict, key, -1);
                TALLOC_FREE(key);
 
                _pam_log_debug(ctx, LOG_INFO,
@@ -2358,7 +2382,7 @@ static int get_warn_pwd_expire_from_config(struct pwb_context *ctx)
        ret = get_config_item_int(ctx, "warn_pwd_expire",
                                  WINBIND_WARN_PWD_EXPIRE);
        /* no or broken setting */
-       if (ret <= 0) {
+       if (ret < 0) {
                return DEFAULT_DAYS_TO_WARN_BEFORE_PWD_EXPIRES;
        }
        return ret;
@@ -2397,7 +2421,7 @@ static char winbind_get_separator(struct pwb_context *ctx)
  * Convert a upn to a name.
  *
  * @param ctx PAM winbind context.
- * @param upn  USer UPN to be trabslated.
+ * @param upn  User UPN to be translated.
  *
  * @return converted name. NULL pointer on failure. Caller needs to free.
  */
@@ -2412,6 +2436,7 @@ static char* winbind_upn_to_username(struct pwb_context *ctx,
        char *domain = NULL;
        char *name;
        char *p;
+       char *result;
 
        /* This cannot work when the winbind separator = @ */
 
@@ -2443,11 +2468,15 @@ static char* winbind_upn_to_username(struct pwb_context *ctx,
                return NULL;
        }
 
-       return talloc_asprintf(ctx, "%s\\%s", domain, name);
+       result = talloc_asprintf(ctx, "%s%c%s", domain, sep, name);
+       wbcFreeMemory(domain);
+       wbcFreeMemory(name);
+       return result;
 }
 
 static int _pam_delete_cred(pam_handle_t *pamh, int flags,
-                        int argc, const char **argv)
+                           int argc, enum pam_winbind_request_type type, 
+                           const char **argv)
 {
        int retval = PAM_SUCCESS;
        struct pwb_context *ctx = NULL;
@@ -2458,9 +2487,9 @@ static int _pam_delete_cred(pam_handle_t *pamh, int flags,
 
        ZERO_STRUCT(logoff);
 
-       retval = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
+       retval = _pam_winbind_init_context(pamh, flags, argc, argv, type, &ctx);
        if (retval) {
-               goto out;
+               return retval;
        }
 
        _PAM_LOG_FUNCTION_ENTER("_pam_delete_cred", ctx);
@@ -2593,9 +2622,10 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
        char *real_username = NULL;
        struct pwb_context *ctx = NULL;
 
-       retval = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
+       retval = _pam_winbind_init_context(pamh, flags, argc, argv,
+                                          PAM_WINBIND_AUTHENTICATE, &ctx);
        if (retval) {
-               goto out;
+               return retval;
        }
 
        _PAM_LOG_FUNCTION_ENTER("pam_sm_authenticate", ctx);
@@ -2744,9 +2774,10 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags,
        int ret = PAM_SYSTEM_ERR;
        struct pwb_context *ctx = NULL;
 
-       ret = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
+       ret = _pam_winbind_init_context(pamh, flags, argc, argv,
+                                       PAM_WINBIND_SETCRED, &ctx);
        if (ret) {
-               goto out;
+               return ret;
        }
 
        _PAM_LOG_FUNCTION_ENTER("pam_sm_setcred", ctx);
@@ -2754,7 +2785,8 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags,
        switch (flags & ~PAM_SILENT) {
 
                case PAM_DELETE_CRED:
-                       ret = _pam_delete_cred(pamh, flags, argc, argv);
+                       ret = _pam_delete_cred(pamh, flags, argc,
+                                              PAM_WINBIND_SETCRED, argv);
                        break;
                case PAM_REFRESH_CRED:
                        _pam_log_debug(ctx, LOG_WARNING,
@@ -2776,8 +2808,6 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags,
                        break;
        }
 
- out:
-
        _PAM_LOG_FUNCTION_LEAVE("pam_sm_setcred", ctx, ret);
 
        TALLOC_FREE(ctx);
@@ -2795,12 +2825,13 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
 {
        const char *username;
        int ret = PAM_USER_UNKNOWN;
-       void *tmp = NULL;
+       const char *tmp = NULL;
        struct pwb_context *ctx = NULL;
 
-       ret = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
+       ret = _pam_winbind_init_context(pamh, flags, argc, argv,
+                                       PAM_WINBIND_ACCT_MGMT, &ctx);
        if (ret) {
-               goto out;
+               return ret;
        }
 
        _PAM_LOG_FUNCTION_ENTER("pam_sm_acct_mgmt", ctx);
@@ -2836,7 +2867,7 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
                pam_get_data(pamh, PAM_WINBIND_NEW_AUTHTOK_REQD,
                             (const void **)&tmp);
                if (tmp != NULL) {
-                       ret = atoi((const char *)tmp);
+                       ret = atoi(tmp);
                        switch (ret) {
                        case PAM_AUTHTOK_EXPIRED:
                                /* fall through, since new token is required in this case */
@@ -2893,9 +2924,10 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
        int ret = PAM_SUCCESS;
        struct pwb_context *ctx = NULL;
 
-       ret = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
+       ret = _pam_winbind_init_context(pamh, flags, argc, argv,
+                                       PAM_WINBIND_OPEN_SESSION, &ctx);
        if (ret) {
-               goto out;
+               return ret;
        }
 
        _PAM_LOG_FUNCTION_ENTER("pam_sm_open_session", ctx);
@@ -2904,7 +2936,7 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
                /* check and create homedir */
                ret = _pam_mkhomedir(ctx);
        }
- out:
+
        _PAM_LOG_FUNCTION_LEAVE("pam_sm_open_session", ctx, ret);
 
        TALLOC_FREE(ctx);
@@ -2919,14 +2951,14 @@ int pam_sm_close_session(pam_handle_t *pamh, int flags,
        int ret = PAM_SUCCESS;
        struct pwb_context *ctx = NULL;
 
-       ret = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
+       ret = _pam_winbind_init_context(pamh, flags, argc, argv,
+                                       PAM_WINBIND_CLOSE_SESSION, &ctx);
        if (ret) {
-               goto out;
+               return ret;
        }
 
        _PAM_LOG_FUNCTION_ENTER("pam_sm_close_session", ctx);
 
-out:
        _PAM_LOG_FUNCTION_LEAVE("pam_sm_close_session", ctx, ret);
 
        TALLOC_FREE(ctx);
@@ -2962,8 +2994,8 @@ static bool _pam_require_krb5_auth_after_chauthtok(struct pwb_context *ctx,
        char *new_authtok_reqd_during_auth = NULL;
        struct passwd *pwd = NULL;
 
-       _pam_get_data(ctx->pamh, PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH,
-                     &new_authtok_reqd_during_auth);
+       pam_get_data(ctx->pamh, PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH,
+                     (const void **) &new_authtok_reqd_during_auth);
        pam_set_data(ctx->pamh, PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH,
                     NULL, NULL);
 
@@ -2994,7 +3026,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 
        /* <DO NOT free() THESE> */
        const char *user;
-       char *pass_old, *pass_new;
+       const char *pass_old;
+       const char *pass_new;
        /* </DO NOT free() THESE> */
 
        char *Announce;
@@ -3004,9 +3037,10 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
        struct wbcAuthErrorInfo *error = NULL;
        struct pwb_context *ctx = NULL;
 
-       ret = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
+       ret = _pam_winbind_init_context(pamh, flags, argc, argv,
+                                       PAM_WINBIND_CHAUTHTOK, &ctx);
        if (ret) {
-               goto out;
+               return ret;
        }
 
        _PAM_LOG_FUNCTION_ENTER("pam_sm_chauthtok", ctx);
@@ -3117,7 +3151,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                 * get the old token back.
                 */
 
-               ret = _pam_get_item(pamh, PAM_OLDAUTHTOK, &pass_old);
+               ret = pam_get_item(pamh, PAM_OLDAUTHTOK, (const void **) &pass_old);
 
                if (ret != PAM_SUCCESS) {
                        _pam_log(ctx, LOG_NOTICE,
@@ -3167,8 +3201,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                 * By reaching here we have approved the passwords and must now
                 * rebuild the password database file.
                 */
-               _pam_get_data(pamh, PAM_WINBIND_PWD_LAST_SET,
-                             &pwdlastset_update);
+               pam_get_data(pamh, PAM_WINBIND_PWD_LAST_SET,
+                            (const void **) &pwdlastset_update);
 
                /*
                 * if cached creds were enabled, make sure to set the