Proper fix for #6898 - Samba duplicates file content on appending. Pointed out by...
[Samba.git] / source3 / auth / auth_script.c
blob6cbace71e8625dada2b847931212bc9beab18cf4
1 /*
2 Unix SMB/CIFS implementation.
4 Call out to a shell script for an authentication check.
6 Copyright (C) Jeremy Allison 2005.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
24 #undef malloc
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_AUTH
29 /* Create a string containing the supplied :
30 * domain\n
31 * user\n
32 * ascii hex challenge\n
33 * ascii hex LM response\n
34 * ascii hex NT response\n\0
35 * and execute a shell script to check this.
36 * Allows external programs to create users on demand.
37 * Script returns zero on success, non-zero on fail.
40 static NTSTATUS script_check_user_credentials(const struct auth_context *auth_context,
41 void *my_private_data,
42 TALLOC_CTX *mem_ctx,
43 const auth_usersupplied_info *user_info,
44 auth_serversupplied_info **server_info)
46 const char *script = lp_parm_const_string( GLOBAL_SECTION_SNUM, "auth_script", "script", NULL);
47 char *secret_str;
48 size_t secret_str_len;
49 char hex_str[49];
50 int ret, i;
52 if (!script) {
53 return NT_STATUS_INVALID_PARAMETER;
56 if (!user_info) {
57 return NT_STATUS_INVALID_PARAMETER;
60 if (!auth_context) {
61 DEBUG(3,("script_check_user_credentials: no auth_info !\n"));
62 return NT_STATUS_INVALID_PARAMETER;
65 secret_str_len = strlen(user_info->domain) + 1 +
66 strlen(user_info->smb_name) + 1 +
67 16 + 1 + /* 8 bytes of challenge going to 16 */
68 48 + 1 + /* 24 bytes of challenge going to 48 */
69 48 + 1;
71 secret_str = (char *)malloc(secret_str_len);
72 if (!secret_str) {
73 return NT_STATUS_NO_MEMORY;
76 safe_strcpy( secret_str, user_info->domain, secret_str_len - 1);
77 safe_strcat( secret_str, "\n", secret_str_len - 1);
78 safe_strcat( secret_str, user_info->smb_name, secret_str_len - 1);
79 safe_strcat( secret_str, "\n", secret_str_len - 1);
81 for (i = 0; i < 8; i++) {
82 slprintf(&hex_str[i*2], 3, "%02X", auth_context->challenge.data[i]);
84 safe_strcat( secret_str, hex_str, secret_str_len - 1);
85 safe_strcat( secret_str, "\n", secret_str_len - 1);
87 if (user_info->lm_resp.data) {
88 for (i = 0; i < 24; i++) {
89 slprintf(&hex_str[i*2], 3, "%02X", user_info->lm_resp.data[i]);
91 safe_strcat( secret_str, hex_str, secret_str_len - 1);
93 safe_strcat( secret_str, "\n", secret_str_len - 1);
95 if (user_info->nt_resp.data) {
96 for (i = 0; i < 24; i++) {
97 slprintf(&hex_str[i*2], 3, "%02X", user_info->nt_resp.data[i]);
99 safe_strcat( secret_str, hex_str, secret_str_len - 1);
101 safe_strcat( secret_str, "\n", secret_str_len - 1);
103 DEBUG(10,("script_check_user_credentials: running %s with parameters:\n%s\n",
104 script, secret_str ));
106 ret = smbrunsecret( script, secret_str);
108 SAFE_FREE(secret_str);
110 if (ret) {
111 DEBUG(1,("script_check_user_credentials: failed to authenticate %s\\%s\n",
112 user_info->domain, user_info->smb_name ));
113 /* auth failed. */
114 return NT_STATUS_NO_SUCH_USER;
117 /* Cause the auth system to keep going.... */
118 return NT_STATUS_NOT_IMPLEMENTED;
121 /* module initialisation */
122 static NTSTATUS auth_init_script(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
124 if (!make_auth_methods(auth_context, auth_method)) {
125 return NT_STATUS_NO_MEMORY;
128 (*auth_method)->name = "script";
129 (*auth_method)->auth = script_check_user_credentials;
131 if (param && *param) {
132 /* we load the 'fallback' module - if script isn't here, call this
133 module */
134 auth_methods *priv;
135 if (!load_auth_module(auth_context, param, &priv)) {
136 return NT_STATUS_UNSUCCESSFUL;
138 (*auth_method)->private_data = (void *)priv;
140 return NT_STATUS_OK;
143 NTSTATUS auth_script_init(void);
144 NTSTATUS auth_script_init(void)
146 return smb_register_auth(AUTH_INTERFACE_VERSION, "script", auth_init_script);