diff options
author | Garming Sam <garming@catalyst.net.nz> | 2016-04-01 10:10:57 +1300 |
---|---|---|
committer | Garming Sam <garming@samba.org> | 2016-07-05 00:00:14 +0200 |
commit | 878fa6ef7de420ed7f28e95113bb76bf50879553 (patch) | |
tree | 433d00319c42fc186b657c11f174922273a80336 /source4/dsdb/common/util.c | |
parent | 5a0d1b7cc5769e3f4236f81cb45d8533339a3cfd (diff) | |
download | samba-878fa6ef7de420ed7f28e95113bb76bf50879553.tar.gz |
check-password-script: Allow AD to execute these scripts
In contrast to source3, this is run as root and without substitution.
Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source4/dsdb/common/util.c')
-rw-r--r-- | source4/dsdb/common/util.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 69f0f631de8..2a1e44b5263 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -44,6 +44,7 @@ #include "lib/socket/socket.h" #include "librpc/gen_ndr/irpc.h" #include "libds/common/flag_mapping.h" +#include "../lib/util/util_runcmd.h" /* search the sam for the specified attributes in a specific domain, filter on @@ -1988,12 +1989,15 @@ int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, * * Result codes from "enum samr_ValidationStatus" (consider "samr.idl") */ -enum samr_ValidationStatus samdb_check_password(const DATA_BLOB *utf8_blob, +enum samr_ValidationStatus samdb_check_password(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + const DATA_BLOB *utf8_blob, const uint32_t pwdProperties, const uint32_t minPwdLength) { const char *utf8_pw = (const char *)utf8_blob->data; size_t utf8_len = strlen_m(utf8_pw); + char *password_script = NULL; /* checks if the "minPwdLength" property is satisfied */ if (minPwdLength > utf8_len) { @@ -2009,6 +2013,61 @@ enum samr_ValidationStatus samdb_check_password(const DATA_BLOB *utf8_blob, return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH; } + password_script = lpcfg_check_password_script(lp_ctx, mem_ctx); + if (password_script != NULL && *password_script != '\0') { + int check_ret = 0; + int error = 0; + struct tevent_context *event_ctx = NULL; + struct tevent_req *req = NULL; + struct samba_runcmd_state *run_cmd = NULL; + const char * const cmd[4] = { + "/bin/sh", "-c", + password_script, + NULL + }; + + event_ctx = tevent_context_init(mem_ctx); + if (event_ctx == NULL) { + TALLOC_FREE(password_script); + return SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR; + } + + req = samba_runcmd_send(mem_ctx, event_ctx, + tevent_timeval_current_ofs(0, 10000000), + 100, 100, cmd, NULL); + run_cmd = tevent_req_data(req, struct samba_runcmd_state); + if (write(run_cmd->fd_stdin, utf8_pw, utf8_len) != utf8_len) { + TALLOC_FREE(password_script); + return SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR; + } + + close(run_cmd->fd_stdin); + run_cmd->fd_stdin = -1; + + if (!tevent_req_poll(req, event_ctx)) { + TALLOC_FREE(password_script); + return SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR; + } + + check_ret = samba_runcmd_recv(req, &error); + TALLOC_FREE(req); + + DEBUG(5,("check_password_complexity: check password script (%s) " + "returned [%d]\n", password_script, check_ret)); + TALLOC_FREE(password_script); + + if (check_ret != 0) { + DEBUG(1,("check_password_complexity: " + "check password script said new password is not good " + "enough!\n")); + return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH; + } + + return SAMR_VALIDATION_STATUS_SUCCESS; + } + + TALLOC_FREE(password_script); + if (!check_password_quality(utf8_pw)) { return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH; } |