1/* 2 * Unix SMB/CIFS implementation. 3 * NetApi Support 4 * Copyright (C) Guenther Deschner 2007-2008 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20#include "includes.h" 21#include "lib/netapi/netapi.h" 22#include "lib/netapi/netapi_private.h" 23 24extern bool AllowDebugChange; 25 26struct libnetapi_ctx *stat_ctx = NULL; 27TALLOC_CTX *frame = NULL; 28static bool libnetapi_initialized = false; 29 30/**************************************************************** 31****************************************************************/ 32 33static NET_API_STATUS libnetapi_init_private_context(struct libnetapi_ctx *ctx) 34{ 35 struct libnetapi_private_ctx *priv; 36 37 if (!ctx) { 38 return W_ERROR_V(WERR_INVALID_PARAM); 39 } 40 41 priv = TALLOC_ZERO_P(ctx, struct libnetapi_private_ctx); 42 if (!priv) { 43 return W_ERROR_V(WERR_NOMEM); 44 } 45 46 ctx->private_data = priv; 47 48 return NET_API_STATUS_SUCCESS; 49} 50 51/**************************************************************** 52****************************************************************/ 53 54NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) 55{ 56 NET_API_STATUS status; 57 struct libnetapi_ctx *ctx = NULL; 58 char *krb5_cc_env = NULL; 59 60 if (stat_ctx && libnetapi_initialized) { 61 *context = stat_ctx; 62 return NET_API_STATUS_SUCCESS; 63 } 64 65#if 0 66 talloc_enable_leak_report(); 67#endif 68 frame = talloc_stackframe(); 69 70 ctx = talloc_zero(frame, struct libnetapi_ctx); 71 if (!ctx) { 72 TALLOC_FREE(frame); 73 return W_ERROR_V(WERR_NOMEM); 74 } 75 76 if (!DEBUGLEVEL) { 77 DEBUGLEVEL = 0; 78 } 79 80 /* prevent setup_logging() from closing x_stderr... */ 81 dbf = 0; 82 setup_logging("libnetapi", true); 83 84 dbf = x_stderr; 85 x_setbuf(x_stderr, NULL); 86 AllowDebugChange = false; 87 88 load_case_tables(); 89 90 if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, false)) { 91 TALLOC_FREE(frame); 92 fprintf(stderr, "error loading %s\n", get_dyn_CONFIGFILE() ); 93 return W_ERROR_V(WERR_GENERAL_FAILURE); 94 } 95 96 AllowDebugChange = true; 97 98 init_names(); 99 load_interfaces(); 100 reopen_logs(); 101 102 BlockSignals(True, SIGPIPE); 103 104 krb5_cc_env = getenv(KRB5_ENV_CCNAME); 105 if (!krb5_cc_env || (strlen(krb5_cc_env) == 0)) { 106 ctx->krb5_cc_env = talloc_strdup(frame, "MEMORY:libnetapi"); 107 setenv(KRB5_ENV_CCNAME, ctx->krb5_cc_env, 1); 108 } 109 110 if (getenv("USER")) { 111 ctx->username = talloc_strdup(frame, getenv("USER")); 112 } else { 113 ctx->username = talloc_strdup(frame, ""); 114 } 115 if (!ctx->username) { 116 TALLOC_FREE(frame); 117 fprintf(stderr, "libnetapi_init: out of memory\n"); 118 return W_ERROR_V(WERR_NOMEM); 119 } 120 121 status = libnetapi_init_private_context(ctx); 122 if (status != 0) { 123 TALLOC_FREE(frame); 124 return status; 125 } 126 127 libnetapi_initialized = true; 128 129 *context = stat_ctx = ctx; 130 131 return NET_API_STATUS_SUCCESS; 132} 133 134/**************************************************************** 135****************************************************************/ 136 137NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx) 138{ 139 if (stat_ctx) { 140 *ctx = stat_ctx; 141 return NET_API_STATUS_SUCCESS; 142 } 143 144 return libnetapi_init(ctx); 145} 146 147/**************************************************************** 148****************************************************************/ 149 150NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) 151{ 152 if (!ctx) { 153 return NET_API_STATUS_SUCCESS; 154 } 155 156 libnetapi_samr_free(ctx); 157 158 libnetapi_shutdown_cm(ctx); 159 160 if (ctx->krb5_cc_env) { 161 char *env = getenv(KRB5_ENV_CCNAME); 162 if (env && (strequal(ctx->krb5_cc_env, env))) { 163 unsetenv(KRB5_ENV_CCNAME); 164 } 165 } 166 167 gfree_names(); 168 gfree_loadparm(); 169 gfree_case_tables(); 170 gfree_charcnv(); 171 gfree_interfaces(); 172 173 secrets_shutdown(); 174 175 TALLOC_FREE(ctx); 176 TALLOC_FREE(frame); 177 178 gfree_debugsyms(); 179 180 return NET_API_STATUS_SUCCESS; 181} 182 183/**************************************************************** 184****************************************************************/ 185 186NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx, 187 const char *debuglevel) 188{ 189 AllowDebugChange = true; 190 ctx->debuglevel = talloc_strdup(ctx, debuglevel); 191 if (!debug_parse_levels(debuglevel)) { 192 return W_ERROR_V(WERR_GENERAL_FAILURE); 193 } 194 return NET_API_STATUS_SUCCESS; 195} 196 197/**************************************************************** 198****************************************************************/ 199 200NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, 201 char **debuglevel) 202{ 203 *debuglevel = ctx->debuglevel; 204 return NET_API_STATUS_SUCCESS; 205} 206 207/**************************************************************** 208****************************************************************/ 209 210NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, 211 const char *username) 212{ 213 TALLOC_FREE(ctx->username); 214 ctx->username = talloc_strdup(ctx, username ? username : ""); 215 216 if (!ctx->username) { 217 return W_ERROR_V(WERR_NOMEM); 218 } 219 return NET_API_STATUS_SUCCESS; 220} 221 222NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx, 223 const char *password) 224{ 225 TALLOC_FREE(ctx->password); 226 ctx->password = talloc_strdup(ctx, password); 227 if (!ctx->password) { 228 return W_ERROR_V(WERR_NOMEM); 229 } 230 return NET_API_STATUS_SUCCESS; 231} 232 233NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, 234 const char *workgroup) 235{ 236 TALLOC_FREE(ctx->workgroup); 237 ctx->workgroup = talloc_strdup(ctx, workgroup); 238 if (!ctx->workgroup) { 239 return W_ERROR_V(WERR_NOMEM); 240 } 241 return NET_API_STATUS_SUCCESS; 242} 243 244/**************************************************************** 245****************************************************************/ 246 247NET_API_STATUS libnetapi_set_use_kerberos(struct libnetapi_ctx *ctx) 248{ 249 ctx->use_kerberos = true; 250 return NET_API_STATUS_SUCCESS; 251} 252 253NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx) 254{ 255 ctx->use_ccache = true; 256 return NET_API_STATUS_SUCCESS; 257} 258 259/**************************************************************** 260****************************************************************/ 261 262const char *libnetapi_errstr(NET_API_STATUS status) 263{ 264 if (status & 0xc0000000) { 265 return get_friendly_nt_error_msg(NT_STATUS(status)); 266 } 267 268 return get_friendly_werror_msg(W_ERROR(status)); 269} 270 271/**************************************************************** 272****************************************************************/ 273 274NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx, 275 const char *format, ...) 276{ 277 va_list args; 278 279 TALLOC_FREE(ctx->error_string); 280 281 va_start(args, format); 282 ctx->error_string = talloc_vasprintf(ctx, format, args); 283 va_end(args); 284 285 if (!ctx->error_string) { 286 return W_ERROR_V(WERR_NOMEM); 287 } 288 return NET_API_STATUS_SUCCESS; 289} 290 291/**************************************************************** 292****************************************************************/ 293 294const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx, 295 NET_API_STATUS status_in) 296{ 297 NET_API_STATUS status; 298 struct libnetapi_ctx *tmp_ctx = ctx; 299 300 if (!tmp_ctx) { 301 status = libnetapi_getctx(&tmp_ctx); 302 if (status != 0) { 303 return NULL; 304 } 305 } 306 307 if (tmp_ctx->error_string) { 308 return tmp_ctx->error_string; 309 } 310 311 return libnetapi_errstr(status_in); 312} 313 314/**************************************************************** 315****************************************************************/ 316 317NET_API_STATUS NetApiBufferAllocate(uint32_t byte_count, 318 void **buffer) 319{ 320 void *buf = NULL; 321 322 if (!buffer) { 323 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER); 324 } 325 326 if (byte_count == 0) { 327 goto done; 328 } 329 330 buf = talloc_size(NULL, byte_count); 331 if (!buf) { 332 return W_ERROR_V(WERR_NOMEM); 333 } 334 335 done: 336 *buffer = buf; 337 338 return NET_API_STATUS_SUCCESS; 339} 340 341/**************************************************************** 342****************************************************************/ 343 344NET_API_STATUS NetApiBufferFree(void *buffer) 345{ 346 if (!buffer) { 347 return W_ERROR_V(WERR_INSUFFICIENT_BUFFER); 348 } 349 350 talloc_free(buffer); 351 352 return NET_API_STATUS_SUCCESS; 353} 354