/*ARGSUSED*/ static long krb5int_get_plugin_sym (struct plugin_file_handle *h, const char *csymname, int isfunc, void **ptr, struct errinfo *ep) { long err = 0; void *sym = NULL; #if USE_DLOPEN if (!err && !sym && (h->dlhandle != NULL)) { /* XXX Do we need to add a leading "_" to the symbol name on any modern platforms? */ sym = dlsym (h->dlhandle, csymname); if (sym == NULL) { const char *e = dlerror (); /* XXX copy and save away */ Tprintf ("dlsym(%s): %s\n", csymname, e); err = ENOENT; /* XXX */ krb5int_set_error(ep, err, "%s", e); } } #endif #if USE_CFBUNDLE if (!err && !sym && (h->bundle != NULL)) { CFStringRef cfsymname = NULL; if (!err) { cfsymname = CFStringCreateWithCString (kCFAllocatorDefault, csymname, kCFStringEncodingASCII); if (cfsymname == NULL) { err = ENOMEM; } } if (!err) { if (isfunc) { sym = CFBundleGetFunctionPointerForName (h->bundle, cfsymname); } else { sym = CFBundleGetDataPointerForName (h->bundle, cfsymname); } if (sym == NULL) { err = ENOENT; } /* XXX */ } if (cfsymname != NULL) { CFRelease (cfsymname); } } #endif if (!err && (sym == NULL)) { err = ENOENT; /* unimplemented */ } if (!err) { *ptr = sym; } return err; }
/* Set the error message state of dest_ctx to that of src_ctx. */ void KRB5_CALLCONV krb5_copy_error_message (krb5_context dest_ctx, krb5_context src_ctx) { if (dest_ctx == src_ctx) return; if (src_ctx->err.msg) { krb5int_set_error(&dest_ctx->err, src_ctx->err.code, "%s", src_ctx->err.msg); } else { krb5int_clear_error(&dest_ctx->err); } }
static krb5_gic_opt_ext * krb5int_gic_opte_alloc(krb5_context context) { krb5_gic_opt_ext *opte; krb5_error_code code; opte = calloc(1, sizeof(*opte)); if (NULL == opte) return NULL; opte->flags = KRB5_GET_INIT_CREDS_OPT_EXTENDED; code = krb5int_gic_opte_private_alloc(context, opte); if (code) { krb5int_set_error(&context->err, code, "krb5int_gic_opte_alloc: krb5int_gic_opte_private_alloc failed"); free(opte); return NULL; } return(opte); }
/* * Convert a krb5_get_init_creds_opt pointer to a pointer to * an extended, krb5_gic_opt_ext pointer. If the original * pointer already points to an extended structure, then simply * return the original pointer. Otherwise, if 'force' is non-zero, * allocate an extended structure and copy the original over it. * If the original pointer did not point to an extended structure * and 'force' is zero, then return an error. This is used in * cases where the original *should* be an extended structure. */ krb5_error_code krb5int_gic_opt_to_opte(krb5_context context, krb5_get_init_creds_opt *opt, krb5_gic_opt_ext **opte, unsigned int force, const char *where) { if (!krb5_gic_opt_is_extended(opt)) { if (force) { return krb5int_gic_opte_copy(context, opt, opte); } else { krb5int_set_error(&context->err, EINVAL, "%s: attempt to convert non-extended krb5_get_init_creds_opt", where); return EINVAL; } } /* If it is already extended, just return it */ *opte = (krb5_gic_opt_ext *)opt; return 0; }
krb5_error_code KRB5_CALLCONV krb5_c_decrypt(krb5_context context, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, const krb5_enc_data *input, krb5_data *output) { int i; for (i=0; i<krb5_enctypes_length; i++) { if (krb5_enctypes_list[i].etype == key->enctype) break; } if (i == krb5_enctypes_length) { krb5int_set_error(&context->err, KRB5_BAD_ENCTYPE, "Bad encryption type (type %d unknown)", key->enctype); return(KRB5_BAD_ENCTYPE); } if ((input->enctype != ENCTYPE_UNKNOWN) && (krb5_enctypes_list[i].etype != input->enctype)) return(KRB5_BAD_ENCTYPE); if (krb5_enctypes_list[i].decrypt == NULL) { assert(krb5_enctypes_list[i].aead != NULL); return krb5int_c_decrypt_aead_compat(krb5_enctypes_list[i].aead, krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash, key, usage, ivec, &input->ciphertext, output); } return((*(krb5_enctypes_list[i].decrypt)) (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash, key, usage, ivec, &input->ciphertext, output)); }
/*ARGSUSED2*/ long KRB5_CALLCONV krb5int_open_plugin (const char *filepath, struct plugin_file_handle **h, struct errinfo *ep) { long err = 0; struct stat statbuf; struct plugin_file_handle *htmp = NULL; int got_plugin = 0; if (!err) { if (stat (filepath, &statbuf) < 0) { Tprintf ("stat(%s): %s\n", filepath, strerror (errno)); err = errno; } } if (!err) { htmp = calloc (1, sizeof (*htmp)); /* calloc initializes ptrs to NULL */ if (htmp == NULL) { err = errno; } } #if USE_DLOPEN if (!err && (statbuf.st_mode & S_IFMT) == S_IFREG) { void *handle = NULL; #ifdef RTLD_GROUP #define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL | RTLD_GROUP) #else #define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL) #endif if (!err) { handle = dlopen(filepath, PLUGIN_DLOPEN_FLAGS); if (handle == NULL) { const char *e = dlerror(); Tprintf ("dlopen(%s): %s\n", filepath, e); err = ENOENT; /* XXX */ krb5int_set_error (ep, err, "%s", e); } } if (!err) { got_plugin = 1; htmp->dlhandle = handle; handle = NULL; } if (handle != NULL) { dlclose (handle); } } #endif #if USE_CFBUNDLE if (!err && (statbuf.st_mode & S_IFMT) == S_IFDIR) { CFStringRef pluginPath = NULL; CFURLRef pluginURL = NULL; CFBundleRef pluginBundle = NULL; if (!err) { pluginPath = CFStringCreateWithCString (kCFAllocatorDefault, filepath, kCFStringEncodingASCII); if (pluginPath == NULL) { err = ENOMEM; } } if (!err) { pluginURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, pluginPath, kCFURLPOSIXPathStyle, true); if (pluginURL == NULL) { err = ENOMEM; } } if (!err) { pluginBundle = CFBundleCreate (kCFAllocatorDefault, pluginURL); if (pluginBundle == NULL) { err = ENOENT; } /* XXX need better error */ } if (!err) { if (!CFBundleIsExecutableLoaded (pluginBundle)) { int loaded = CFBundleLoadExecutable (pluginBundle); if (!loaded) { err = ENOENT; } /* XXX need better error */ } } if (!err) { got_plugin = 1; htmp->bundle = pluginBundle; pluginBundle = NULL; /* htmp->bundle takes ownership */ } if (pluginBundle != NULL) { CFRelease (pluginBundle); } if (pluginURL != NULL) { CFRelease (pluginURL); } if (pluginPath != NULL) { CFRelease (pluginPath); } } #endif if (!err && !got_plugin) { err = ENOENT; /* no plugin or no way to load plugins */ } if (!err) { *h = htmp; htmp = NULL; /* h takes ownership */ } if (htmp != NULL) { free (htmp); } return err; }
static long krb5int_get_plugin_sym (struct plugin_file_handle *h, const char *csymname, int isfunc, void **ptr, struct errinfo *ep) { long err = 0; void *sym = NULL; #if USE_DLOPEN if (!err && !sym && (h->dlhandle != NULL)) { /* XXX Do we need to add a leading "_" to the symbol name on any modern platforms? */ sym = dlsym (h->dlhandle, csymname); if (sym == NULL) { const char *e = dlerror (); /* XXX copy and save away */ if (e == NULL) e = "unknown failure"; Tprintf ("dlsym(%s): %s\n", csymname, e); err = ENOENT; /* XXX */ krb5int_set_error(ep, err, "%s", e); } } #endif #ifdef _WIN32 LPVOID lpMsgBuf; DWORD dw; if (!err && !sym && (h->hinstPlugin != NULL)) { sym = GetProcAddress(h->hinstPlugin, csymname); if (sym == NULL) { const char *e = "unable to get dll symbol"; /* XXX copy and save away */ Tprintf ("GetProcAddress(%s): %s\n", csymname, GetLastError()); err = ENOENT; /* XXX */ krb5int_set_error(ep, err, "%s", e); dw = GetLastError(); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL )) { fprintf (stderr, "unable to get dll symbol, %s\n", (LPCTSTR)lpMsgBuf); LocalFree(lpMsgBuf); } } } #endif if (!err && (sym == NULL)) { err = ENOENT; /* unimplemented */ } if (!err) { *ptr = sym; } return err; }
long KRB5_CALLCONV krb5int_open_plugin (const char *filepath, struct plugin_file_handle **h, struct errinfo *ep) { long err = 0; struct stat statbuf; struct plugin_file_handle *htmp = NULL; int got_plugin = 0; if (!err) { if (stat (filepath, &statbuf) < 0) { Tprintf ("stat(%s): %s\n", filepath, strerror (errno)); err = errno; } } if (!err) { htmp = calloc (1, sizeof (*htmp)); /* calloc initializes ptrs to NULL */ if (htmp == NULL) { err = ENOMEM; } } #if USE_DLOPEN if (!err && ((statbuf.st_mode & S_IFMT) == S_IFREG #if USE_CFBUNDLE || (statbuf.st_mode & S_IFMT) == S_IFDIR #endif /* USE_CFBUNDLE */ )) { void *handle = NULL; #if USE_CFBUNDLE char executablepath[MAXPATHLEN]; if ((statbuf.st_mode & S_IFMT) == S_IFDIR) { int lock_err = 0; CFStringRef pluginString = NULL; CFURLRef pluginURL = NULL; CFBundleRef pluginBundle = NULL; CFURLRef executableURL = NULL; /* Lock around CoreFoundation calls since objects are refcounted * and the refcounts are not thread-safe. Using pthreads directly * because this code is Mac-specific */ lock_err = pthread_mutex_lock(&krb5int_bundle_mutex); if (lock_err) { err = lock_err; } if (!err) { pluginString = CFStringCreateWithCString (kCFAllocatorDefault, filepath, kCFStringEncodingASCII); if (pluginString == NULL) { err = ENOMEM; } } if (!err) { pluginURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, pluginString, kCFURLPOSIXPathStyle, true); if (pluginURL == NULL) { err = ENOMEM; } } if (!err) { pluginBundle = CFBundleCreate (kCFAllocatorDefault, pluginURL); if (pluginBundle == NULL) { err = ENOENT; } /* XXX need better error */ } if (!err) { executableURL = CFBundleCopyExecutableURL (pluginBundle); if (executableURL == NULL) { err = ENOMEM; } } if (!err) { if (!CFURLGetFileSystemRepresentation (executableURL, true, /* absolute */ (UInt8 *)executablepath, sizeof (executablepath))) { err = ENOMEM; } } if (!err) { /* override the path the caller passed in */ filepath = executablepath; } if (executableURL != NULL) { CFRelease (executableURL); } if (pluginBundle != NULL) { CFRelease (pluginBundle); } if (pluginURL != NULL) { CFRelease (pluginURL); } if (pluginString != NULL) { CFRelease (pluginString); } /* unlock after CFRelease calls since they modify refcounts */ if (!lock_err) { pthread_mutex_unlock (&krb5int_bundle_mutex); } } #endif /* USE_CFBUNDLE */ /* 32bit PARISC HP-UX does not support the RTLD_GROUP flag */ #if defined(RTLD_GROUP) && !defined(__hppa__) #define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL | RTLD_GROUP) #else #define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL) #endif if (!err) { handle = dlopen(filepath, PLUGIN_DLOPEN_FLAGS); if (handle == NULL) { const char *e = dlerror(); if (e == NULL) e = "unknown failure"; Tprintf ("dlopen(%s): %s\n", filepath, e); err = ENOENT; /* XXX */ krb5int_set_error (ep, err, "%s", e); } } if (!err) { got_plugin = 1; htmp->dlhandle = handle; handle = NULL; } if (handle != NULL) { dlclose (handle); } } #endif /* USE_DLOPEN */ #ifdef _WIN32 if (!err && (statbuf.st_mode & S_IFMT) == S_IFREG) { HMODULE handle = NULL; handle = LoadLibrary(filepath); if (handle == NULL) { Tprintf ("Unable to load dll: %s\n", filepath); err = ENOENT; /* XXX */ krb5int_set_error (ep, err, "%s", "unable to load dll"); } if (!err) { got_plugin = 1; htmp->hinstPlugin = handle; handle = NULL; } if (handle != NULL) FreeLibrary(handle); } #endif if (!err && !got_plugin) { err = ENOENT; /* no plugin or no way to load plugins */ } if (!err) { *h = htmp; htmp = NULL; /* h takes ownership */ } if (htmp != NULL) { free (htmp); } return err; }