diff --git a/source3/Makefile.in b/source3/Makefile.in index 3ef197bcf24..d3cb86e5d7c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -2182,10 +2182,10 @@ bin/winbind_krb5_locator.@SHLIBEXT@: $(BINARY_PREREQS) $(WINBIND_KRB5_LOCATOR_OB @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_KRB5_LOCATOR_OBJ) $(WINBIND_LIBS) \ @SONAMEFLAG@`basename $@` -bin/pam_winbind.@SHLIBEXT@: $(BINARY_PREREQS) $(PAM_WINBIND_OBJ) +bin/pam_winbind.@SHLIBEXT@: $(BINARY_PREREQS) $(PAM_WINBIND_OBJ) @LIBTALLOC_SHARED@ @echo "Linking shared library $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_WINBIND_OBJ) -lpam @INIPARSERLIBS@ \ - $(PAM_WINBIND_EXTRA_LIBS) @SONAMEFLAG@`basename $@` + $(PAM_WINBIND_EXTRA_LIBS) $(LIBTALLOC_LIBS) @SONAMEFLAG@`basename $@` bin/builtin.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_BUILTIN_OBJ) @echo "Building plugin $@" diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index beb0d47baaf..cdb30edad44 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -452,13 +452,17 @@ config_from_pam: return ctrl; }; -static void _pam_winbind_free_context(struct pwb_context *ctx) +static int _pam_winbind_free_context(struct pwb_context *ctx) { + if (!ctx) { + return 0; + } + if (ctx->dict) { iniparser_freedict(ctx->dict); } - SAFE_FREE(ctx); + return 0; } static int _pam_winbind_init_context(pam_handle_t *pamh, @@ -469,12 +473,12 @@ static int _pam_winbind_init_context(pam_handle_t *pamh, { struct pwb_context *r = NULL; - r = (struct pwb_context *)malloc(sizeof(struct pwb_context)); + r = TALLOC_ZERO_P(NULL, struct pwb_context); if (!r) { return PAM_BUF_ERR; } - ZERO_STRUCTP(r); + talloc_set_destructor(r, _pam_winbind_free_context); r->pamh = pamh; r->flags = flags; @@ -482,7 +486,7 @@ static int _pam_winbind_init_context(pam_handle_t *pamh, r->argv = argv; r->ctrl = _pam_parse(pamh, flags, argc, argv, &r->dict); if (r->ctrl == -1) { - _pam_winbind_free_context(r); + TALLOC_FREE(r); return PAM_SYSTEM_ERR; } @@ -502,7 +506,7 @@ static void _pam_winbind_cleanup_func(pam_handle_t *pamh, "(error_status = %d)", pamh, data, error_status); } - SAFE_FREE(data); + TALLOC_FREE(data); } @@ -1104,14 +1108,13 @@ static void _pam_set_data_string(struct pwb_context *ctx, return; } - ret = pam_set_data(ctx->pamh, data_name, (void *)strdup(value), + ret = pam_set_data(ctx->pamh, data_name, talloc_strdup(NULL, value), _pam_winbind_cleanup_func); if (ret) { _pam_log_debug(ctx, LOG_DEBUG, "Could not set data %s: %s\n", data_name, pam_strerror(ctx->pamh, ret)); } - } /** @@ -1224,69 +1227,59 @@ static void _pam_warn_krb5_failure(struct pwb_context *ctx, * @return string (caller needs to free). */ -static char *_pam_compose_pwd_restriction_string(struct winbindd_response *response) +static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx, + struct winbindd_response *response) { char *str = NULL; - size_t offset = 0, ret = 0, str_size = 1024; - str = (char *)malloc(str_size); + str = talloc_asprintf(ctx, "Your password "); if (!str) { - return NULL; - } - - memset(str, '\0', str_size); - - offset = snprintf(str, str_size, "Your password "); - if (offset == -1) { goto failed; } if (response->data.auth.policy.min_length_password > 0) { - ret = snprintf(str+offset, str_size-offset, + str = talloc_asprintf_append(str, "must be at least %d characters; ", response->data.auth.policy.min_length_password); - if (ret == -1) { + if (!str) { goto failed; } - offset += ret; } if (response->data.auth.policy.password_history > 0) { - ret = snprintf(str+offset, str_size-offset, + str = talloc_asprintf_append(str, "cannot repeat any of your previous %d " "passwords; ", response->data.auth.policy.password_history); - if (ret == -1) { + if (!str) { goto failed; } - offset += ret; } if (response->data.auth.policy.password_properties & DOMAIN_PASSWORD_COMPLEX) { - ret = snprintf(str+offset, str_size-offset, + str = talloc_asprintf_append(str, "must contain capitals, numerals " "or punctuation; " "and cannot contain your account " "or full name; "); - if (ret == -1) { + if (!str) { goto failed; } - offset += ret; } - ret = snprintf(str+offset, str_size-offset, + str = talloc_asprintf_append(str, "Please type a different password. " "Type a password which meets these requirements in " "both text boxes."); - if (ret == -1) { + if (!str) { goto failed; } return str; failed: - SAFE_FREE(str); + TALLOC_FREE(str); return NULL; } @@ -1590,11 +1583,11 @@ static int winbind_chauthtok_request(struct pwb_context *ctx, } pwd_restriction_string = - _pam_compose_pwd_restriction_string(&response); + _pam_compose_pwd_restriction_string(ctx, &response); if (pwd_restriction_string) { _make_remark(ctx, PAM_ERROR_MSG, pwd_restriction_string); - SAFE_FREE(pwd_restriction_string); + TALLOC_FREE(pwd_restriction_string); } } @@ -1846,12 +1839,13 @@ static const char *get_conf_item_string(struct pwb_context *ctx, if (ctx->dict) { char *key = NULL; - if (!asprintf(&key, "global:%s", item)) { + key = talloc_asprintf(ctx, "global:%s", item); + if (!key) { goto out; } parm_opt = iniparser_getstr(ctx->dict, key); - SAFE_FREE(key); + TALLOC_FREE(key); _pam_log_debug(ctx, LOG_INFO, "CONFIG file: %s '%s'\n", item, parm_opt); @@ -1893,12 +1887,13 @@ static int get_config_item_int(struct pwb_context *ctx, if (ctx->dict) { char *key = NULL; - if (!asprintf(&key, "global:%s", item)) { + key = talloc_asprintf(ctx, "global:%s", item); + if (!key) { goto out; } parm_opt = iniparser_getint(ctx->dict, key, -1); - SAFE_FREE(key); + TALLOC_FREE(key); _pam_log_debug(ctx, LOG_INFO, "CONFIG file: %s '%d'\n", @@ -1977,8 +1972,6 @@ static char* winbind_upn_to_username(struct pwb_context *ctx, struct winbindd_request req; struct winbindd_response resp; int retval; - char *account_name; - int account_name_len; char sep; /* This cannot work when the winbind separator = @ */ @@ -2014,11 +2007,9 @@ static char* winbind_upn_to_username(struct pwb_context *ctx, return NULL; } - account_name_len = asprintf(&account_name, "%s\\%s", - resp.data.name.dom_name, - resp.data.name.name); - - return account_name; + return talloc_asprintf(ctx, "%s\\%s", + resp.data.name.dom_name, + resp.data.name.name); } PAM_EXTERN @@ -2087,7 +2078,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, real_username); if (samaccountname) { free(real_username); - real_username = samaccountname; + real_username = strdup(samaccountname); } } @@ -2127,7 +2118,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, char *new_authtok_required_during_auth = NULL; - if (!asprintf(&new_authtok_required, "%d", retval)) { + new_authtok_required = talloc_asprintf(NULL, "%d", retval); + if (!new_authtok_required) { retval = PAM_BUF_ERR; goto out; } @@ -2138,7 +2130,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, retval = PAM_SUCCESS; - if (!asprintf(&new_authtok_required_during_auth, "%d", true)) { + new_authtok_required_during_auth = talloc_asprintf(NULL, "%d", true); + if (!new_authtok_required_during_auth) { retval = PAM_BUF_ERR; goto out; } @@ -2172,7 +2165,7 @@ out: _PAM_LOG_FUNCTION_LEAVE("pam_sm_authenticate", ctx, retval); - _pam_winbind_free_context(ctx); + TALLOC_FREE(ctx); return retval; } @@ -2220,7 +2213,7 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, _PAM_LOG_FUNCTION_LEAVE("pam_sm_setcred", ctx, ret); - _pam_winbind_free_context(ctx); + TALLOC_FREE(ctx); return ret; } @@ -2321,7 +2314,7 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, _PAM_LOG_FUNCTION_LEAVE("pam_sm_acct_mgmt", ctx, ret); - _pam_winbind_free_context(ctx); + TALLOC_FREE(ctx); return ret; } @@ -2345,7 +2338,7 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags, out: _PAM_LOG_FUNCTION_LEAVE("pam_sm_open_session", ctx, ret); - _pam_winbind_free_context(ctx); + TALLOC_FREE(ctx); return ret; } @@ -2431,7 +2424,7 @@ out: _PAM_LOG_FUNCTION_LEAVE("pam_sm_close_session", ctx, retval); - _pam_winbind_free_context(ctx); + TALLOC_FREE(ctx); return retval; } @@ -2560,16 +2553,15 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, time_t pwdlastset_prelim = 0; /* instruct user what is happening */ -#define greeting "Changing password for " - Announce = (char *) malloc(sizeof(greeting) + strlen(user)); - if (Announce == NULL) { + +#define greeting "Changing password for" + Announce = talloc_asprintf(ctx, "%s %s", greeting, user); + if (!Announce) { _pam_log(ctx, LOG_CRIT, "password - out of memory"); ret = PAM_BUF_ERR; goto out; } - (void) strcpy(Announce, greeting); - (void) strcpy(Announce + sizeof(greeting) - 1, user); #undef greeting lctrl = ctx->ctrl | WINBIND__OLD_PASSWORD; @@ -2578,6 +2570,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, "(current) NT password: ", NULL, (const char **) &pass_old); + TALLOC_FREE(Announce); if (ret != PAM_SUCCESS) { _pam_log(ctx, LOG_NOTICE, "password - (old) token not obtained"); @@ -2760,7 +2753,7 @@ out: _PAM_LOG_FUNCTION_LEAVE("pam_sm_chauthtok", ctx, ret); - _pam_winbind_free_context(ctx); + TALLOC_FREE(ctx); return ret; } diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h index 6dba127cdc3..425471d0d69 100644 --- a/source3/nsswitch/pam_winbind.h +++ b/source3/nsswitch/pam_winbind.h @@ -7,6 +7,7 @@ #include "../lib/replace/replace.h" #include "system/syslog.h" #include "system/time.h" +#include #define MODULE_NAME "pam_winbind" #define PAM_SM_AUTH @@ -209,3 +210,8 @@ struct pwb_context { dictionary *dict; uint32_t ctrl; }; + +#define TALLOC_FREE(ctx) do { if ((ctx) != NULL) {talloc_free(ctx); ctx=NULL;} } while(0) +#define TALLOC_ZERO_P(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) +#define TALLOC_P(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) +