Imported Upstream version 1.1.6
[platform/upstream/pam.git] / libpam / pam_dynamic.c
1 /*
2  * Redistribution and use in source and binary forms, with or without
3  * modification, are permitted provided that the following conditions
4  * are met:
5  * 1. Redistributions of source code must retain the above copyright
6  *    notice, and the entire permission notice in its entirety,
7  *    including the disclaimer of warranties.
8  * 2. Redistributions in binary form must reproduce the above copyright
9  *    notice, this list of conditions and the following disclaimer in the
10  *    documentation and/or other materials provided with the distribution.
11  * 3. The name of the author may not be used to endorse or promote
12  *    products derived from this software without specific prior
13  *    written permission.
14  *
15  * ALTERNATIVELY, this product may be distributed under the terms of
16  * the GNU Public License, in which case the provisions of the GPL are
17  * required INSTEAD OF the above restrictions.  (This clause is
18  * necessary due to a potential bad interaction between the GPL and
19  * the restrictions contained in a BSD-style copyright.)
20  *
21  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31  * OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include "pam_private.h"
35
36 #ifndef PAM_STATIC
37
38 #ifdef PAM_SHL
39 # include <dl.h>
40 #elif defined(PAM_DYLD)
41 # include <mach-o/dyld.h>
42 #else /* PAM_SHL */
43 # include <dlfcn.h>
44 #endif /* PAM_SHL */
45
46 #ifndef SHLIB_SYM_PREFIX
47 #define SHLIB_SYM_PREFIX "_"
48 #endif
49
50 void *_pam_dlopen(const char *mod_path)
51 {
52 #ifdef PAM_SHL
53         return shl_load(mod_path, BIND_IMMEDIATE, 0L);
54 #elif defined(PAM_DYLD)
55         NSObjectFileImage ofile;
56         void *ret = NULL;
57
58         if (NSCreateObjectFileImageFromFile(mod_path, &ofile) !=
59                         NSObjectFileImageSuccess )
60                 return NULL;
61
62         ret = NSLinkModule(ofile, mod_path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW);
63         NSDestroyObjectFileImage(ofile);
64
65         return ret;
66 #else
67         return dlopen(mod_path, RTLD_NOW);
68 #endif
69 }
70
71 servicefn _pam_dlsym(void *handle, const char *symbol)
72 {
73 #ifdef PAM_SHL
74         char *_symbol = NULL;
75         servicefn ret;
76
77         if( symbol == NULL )
78                 return NULL;
79
80         if( shl_findsym(&handle, symbol, (short) TYPE_PROCEDURE, &ret ){
81                 _symbol = malloc( strlen(symbol) + sizeof(SHLIB_SYM_PREFIX) + 1 );
82                 if( _symbol == NULL )
83                         return NULL;
84                 strcpy(_symbol, SHLIB_SYM_PREFIX);
85                 strcat(_symbol, symbol);
86                 if( shl_findsym(&handle, _symbol,
87                                 (short) TYPE_PROCEDURE, &ret ){
88                         free(_symbol);
89                         return NULL;
90                 }
91                 free(_symbol);
92         }
93
94         return ret;
95
96 #elif defined(PAM_DYLD)
97         NSSymbol nsSymbol;
98         char *_symbol;
99
100         if( symbol == NULL )
101                 return NULL;
102         _symbol = malloc( strlen(symbol) + 2 );
103         if( _symbol == NULL )
104                 return NULL;
105         strcpy(_symbol, SHLIB_SYM_PREFIX);
106         strcat(_symbol, symbol);
107
108         nsSymbol = NSLookupSymbolInModule(handle, _symbol);
109         if( nsSymbol == NULL )
110                 return NULL;
111         free(_symbol);
112
113         return (servicefn)NSAddressOfSymbol(nsSymbol);
114 #else
115         return (servicefn) dlsym(handle, symbol);
116 #endif
117 }
118
119 void _pam_dlclose(void *handle)
120 {
121 #ifdef PAM_SHL
122         shl_unload(handle);
123 #elif defined(PAM_DYLD)
124         NSUnLinkModule((NSModule)handle, NSUNLINKMODULE_OPTION_NONE);
125 #else
126         dlclose(handle);
127 #endif
128
129         return;
130 }
131
132 const char *
133 _pam_dlerror (void)
134 {
135 #if defined(PAM_SHL) || defined(PAM_DYLD)
136         return "unknown";
137 #else
138         return dlerror ();
139 #endif
140 }
141
142 #endif