Changeset 988 for vendor/current/lib/nss_wrapper
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/lib/nss_wrapper
- Files:
-
- 4 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/lib/nss_wrapper/nss_wrapper.c
r740 r988 2 2 * Copyright (C) Stefan Metzmacher 2007 <metze@samba.org> 3 3 * Copyright (C) Guenther Deschner 2009 <gd@samba.org> 4 * Copyright (C) Andreas Schneider 2013 <asn@samba.org> 4 5 * 5 6 * All rights reserved. … … 33 34 */ 34 35 35 #ifdef _SAMBA_BUILD_ 36 37 /* defining this gives us the posix getpwnam_r() calls on solaris 38 Thanks to heimdal for this */ 36 #include "config.h" 37 38 #include <pthread.h> 39 40 #include <sys/types.h> 41 #include <sys/stat.h> 42 #include <sys/socket.h> 43 #include <errno.h> 44 #include <fcntl.h> 45 #include <stdarg.h> 46 #include <stdbool.h> 47 #include <stddef.h> 48 #include <stdio.h> 49 #include <stdint.h> 50 #include <stdlib.h> 51 #include <string.h> 52 #include <unistd.h> 53 #include <ctype.h> 54 55 #include <netinet/in.h> 56 57 #include <search.h> 58 #include <assert.h> 59 60 /* 61 * Defining _POSIX_PTHREAD_SEMANTICS before including pwd.h and grp.h gives us 62 * the posix getpwnam_r(), getpwuid_r(), getgrnam_r and getgrgid_r calls on 63 * Solaris 64 */ 65 #ifndef _POSIX_PTHREAD_SEMANTICS 39 66 #define _POSIX_PTHREAD_SEMANTICS 40 41 #define NSS_WRAPPER_NOT_REPLACE 42 #include "../replace/replace.h" 43 #include "system/passwd.h" 44 #include "system/filesys.h" 45 #include "../nsswitch/nsstest.h" 46 47 #else /* _SAMBA_BUILD_ */ 48 49 #error nss_wrapper_only_supported_in_samba_yet 50 67 #endif 68 69 #include <pwd.h> 70 #include <grp.h> 71 #ifdef HAVE_SHADOW_H 72 #include <shadow.h> 73 #endif /* HAVE_SHADOW_H */ 74 75 #include <netdb.h> 76 #include <arpa/inet.h> 77 #include <netinet/in.h> 78 79 #include <dlfcn.h> 80 81 #if defined(HAVE_NSS_H) 82 /* Linux and BSD */ 83 #include <nss.h> 84 85 typedef enum nss_status NSS_STATUS; 86 #elif defined(HAVE_NSS_COMMON_H) 87 /* Solaris */ 88 #include <nss_common.h> 89 #include <nss_dbdefs.h> 90 #include <nsswitch.h> 91 92 typedef nss_status_t NSS_STATUS; 93 94 # define NSS_STATUS_SUCCESS NSS_SUCCESS 95 # define NSS_STATUS_NOTFOUND NSS_NOTFOUND 96 # define NSS_STATUS_UNAVAIL NSS_UNAVAIL 97 # define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN 98 #else 99 # error "No nsswitch support detected" 100 #endif 101 102 #ifndef PTR_DIFF 103 #define PTR_DIFF(p1, p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2))) 51 104 #endif 52 105 … … 55 108 #endif 56 109 57 /* not all systems have _r functions... */ 58 #ifndef HAVE_GETPWNAM_R 59 #define getpwnam_r(name, pwdst, buf, buflen, pwdstp) ENOSYS 110 #ifndef EAI_NODATA 111 #define EAI_NODATA EAI_NONAME 60 112 #endif 61 #ifndef HAVE_GETPWUID_R 62 #define getpwuid_r(uid, pwdst, buf, buflen, pwdstp) ENOSYS 113 114 #ifndef EAI_ADDRFAMILY 115 #define EAI_ADDRFAMILY EAI_FAMILY 63 116 #endif 64 #ifndef HAVE_GETPWENT_R 65 #define getpwent_r(pwdst, buf, buflen, pwdstp) ENOSYS 117 118 #ifndef __STRING 119 #define __STRING(x) #x 66 120 #endif 67 #ifndef HAVE_GETGRNAM_R 68 #define getgrnam_r(name, grdst, buf, buflen, grdstp) ENOSYS 121 122 #ifndef __STRINGSTRING 123 #define __STRINGSTRING(x) __STRING(x) 69 124 #endif 70 #ifndef HAVE_GETGRGID_R 71 #define getgrgid_r(gid, grdst, buf, buflen, grdstp) ENOSYS 125 126 #ifndef __LINESTR__ 127 #define __LINESTR__ __STRINGSTRING(__LINE__) 72 128 #endif 73 #ifndef HAVE_GETGRENT_R 74 #define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS 129 130 #ifndef __location__ 131 #define __location__ __FILE__ ":" __LINESTR__ 75 132 #endif 76 133 77 /* not all systems have getgrouplist */ 78 #ifndef HAVE_GETGROUPLIST 79 #define getgrouplist(user, group, groups, ngroups) 0 134 #ifndef DNS_NAME_MAX 135 #define DNS_NAME_MAX 255 80 136 #endif 81 137 82 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support 83 * for now */ 84 #define REWRITE_CALLS 85 86 #ifdef REWRITE_CALLS 87 88 #define real_getpwnam getpwnam 89 #define real_getpwnam_r getpwnam_r 90 #define real_getpwuid getpwuid 91 #define real_getpwuid_r getpwuid_r 92 93 #define real_setpwent setpwent 94 #define real_getpwent getpwent 95 #define real_getpwent_r getpwent_r 96 #define real_endpwent endpwent 97 98 /* 99 #define real_getgrlst getgrlst 100 #define real_getgrlst_r getgrlst_r 101 #define real_initgroups_dyn initgroups_dyn 102 */ 103 #define real_initgroups initgroups 104 #define real_getgrouplist getgrouplist 105 106 #define real_getgrnam getgrnam 107 #define real_getgrnam_r getgrnam_r 108 #define real_getgrgid getgrgid 109 #define real_getgrgid_r getgrgid_r 110 111 #define real_setgrent setgrent 112 #define real_getgrent getgrent 113 #define real_getgrent_r getgrent_r 114 #define real_endgrent endgrent 115 138 /* GCC have printf type attribute check. */ 139 #ifdef HAVE_ATTRIBUTE_PRINTF_FORMAT 140 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) 141 #else 142 #define PRINTF_ATTRIBUTE(a,b) 143 #endif /* HAVE_ATTRIBUTE_PRINTF_FORMAT */ 144 145 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE 146 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor)) 147 #else 148 #define DESTRUCTOR_ATTRIBUTE 149 #endif /* HAVE_DESTRUCTOR_ATTRIBUTE */ 150 151 #define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) 152 153 #ifndef SAFE_FREE 154 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) 116 155 #endif 117 156 118 #if 0 119 # ifdef DEBUG 120 # define NWRAP_ERROR(args) DEBUG(0, args) 121 # else 122 # define NWRAP_ERROR(args) printf args 123 # endif 157 #ifdef HAVE_IPV6 158 #define NWRAP_INET_ADDRSTRLEN INET6_ADDRSTRLEN 124 159 #else 125 #define NWRAP_ ERROR(args)160 #define NWRAP_INET_ADDRSTRLEN INET_ADDRSTRLEN 126 161 #endif 127 162 128 #if 0 129 # ifdef DEBUG 130 # define NWRAP_DEBUG(args) DEBUG(0, args) 131 # else 132 # define NWRAP_DEBUG(args) printf args 133 # endif 163 #define NWRAP_LOCK(m) do { \ 164 pthread_mutex_lock(&( m ## _mutex)); \ 165 } while(0) 166 167 #define NWRAP_UNLOCK(m) do { \ 168 pthread_mutex_unlock(&( m ## _mutex)); \ 169 } while(0) 170 171 172 static bool nwrap_initialized = false; 173 static pthread_mutex_t nwrap_initialized_mutex = PTHREAD_MUTEX_INITIALIZER; 174 175 /* The mutex or accessing the id */ 176 static pthread_mutex_t nwrap_global_mutex = PTHREAD_MUTEX_INITIALIZER; 177 static pthread_mutex_t nwrap_gr_global_mutex = PTHREAD_MUTEX_INITIALIZER; 178 static pthread_mutex_t nwrap_he_global_mutex = PTHREAD_MUTEX_INITIALIZER; 179 static pthread_mutex_t nwrap_pw_global_mutex = PTHREAD_MUTEX_INITIALIZER; 180 static pthread_mutex_t nwrap_sp_global_mutex = PTHREAD_MUTEX_INITIALIZER; 181 182 /* Add new global locks here please */ 183 /* Also don't forget to add locks to 184 * nwrap_init() function. 185 */ 186 # define NWRAP_LOCK_ALL do { \ 187 NWRAP_LOCK(nwrap_initialized); \ 188 NWRAP_LOCK(nwrap_global); \ 189 NWRAP_LOCK(nwrap_gr_global); \ 190 NWRAP_LOCK(nwrap_he_global); \ 191 NWRAP_LOCK(nwrap_pw_global); \ 192 NWRAP_LOCK(nwrap_sp_global); \ 193 } while (0); 194 195 # define NWRAP_UNLOCK_ALL do {\ 196 NWRAP_UNLOCK(nwrap_sp_global); \ 197 NWRAP_UNLOCK(nwrap_pw_global); \ 198 NWRAP_UNLOCK(nwrap_he_global); \ 199 NWRAP_UNLOCK(nwrap_gr_global); \ 200 NWRAP_UNLOCK(nwrap_global); \ 201 NWRAP_UNLOCK(nwrap_initialized); \ 202 } while (0); 203 204 static void nwrap_thread_prepare(void) 205 { 206 NWRAP_LOCK_ALL; 207 } 208 209 static void nwrap_thread_parent(void) 210 { 211 NWRAP_UNLOCK_ALL; 212 } 213 214 static void nwrap_thread_child(void) 215 { 216 NWRAP_UNLOCK_ALL; 217 } 218 219 enum nwrap_dbglvl_e { 220 NWRAP_LOG_ERROR = 0, 221 NWRAP_LOG_WARN, 222 NWRAP_LOG_DEBUG, 223 NWRAP_LOG_TRACE 224 }; 225 226 #ifdef NDEBUG 227 # define NWRAP_LOG(...) 134 228 #else 135 #define NWRAP_DEBUG(args) 229 230 static void nwrap_log(enum nwrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4); 231 # define NWRAP_LOG(dbglvl, ...) nwrap_log((dbglvl), __func__, __VA_ARGS__) 232 233 static void nwrap_log(enum nwrap_dbglvl_e dbglvl, 234 const char *func, 235 const char *format, ...) 236 { 237 char buffer[1024]; 238 va_list va; 239 const char *d; 240 unsigned int lvl = 0; 241 int pid = getpid(); 242 243 d = getenv("NSS_WRAPPER_DEBUGLEVEL"); 244 if (d != NULL) { 245 lvl = atoi(d); 246 } 247 248 va_start(va, format); 249 vsnprintf(buffer, sizeof(buffer), format, va); 250 va_end(va); 251 252 if (lvl >= dbglvl) { 253 switch (dbglvl) { 254 case NWRAP_LOG_ERROR: 255 fprintf(stderr, 256 "NWRAP_ERROR(%d) - %s: %s\n", 257 pid, func, buffer); 258 break; 259 case NWRAP_LOG_WARN: 260 fprintf(stderr, 261 "NWRAP_WARN(%d) - %s: %s\n", 262 pid, func, buffer); 263 break; 264 case NWRAP_LOG_DEBUG: 265 fprintf(stderr, 266 "NWRAP_DEBUG(%d) - %s: %s\n", 267 pid, func, buffer); 268 break; 269 case NWRAP_LOG_TRACE: 270 fprintf(stderr, 271 "NWRAP_TRACE(%d) - %s: %s\n", 272 pid, func, buffer); 273 break; 274 } 275 } 276 } 277 #endif /* NDEBUG NWRAP_LOG */ 278 279 struct nwrap_libc_fns { 280 struct passwd *(*_libc_getpwnam)(const char *name); 281 int (*_libc_getpwnam_r)(const char *name, struct passwd *pwd, 282 char *buf, size_t buflen, struct passwd **result); 283 struct passwd *(*_libc_getpwuid)(uid_t uid); 284 int (*_libc_getpwuid_r)(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result); 285 void (*_libc_setpwent)(void); 286 struct passwd *(*_libc_getpwent)(void); 287 #ifdef HAVE_SOLARIS_GETPWENT_R 288 struct passwd *(*_libc_getpwent_r)(struct passwd *pwbuf, char *buf, size_t buflen); 289 #else 290 int (*_libc_getpwent_r)(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp); 136 291 #endif 137 138 #if 0 139 # ifdef DEBUG 140 # define NWRAP_VERBOSE(args) DEBUG(0, args) 141 # else 142 # define NWRAP_VERBOSE(args) printf args 143 # endif 292 void (*_libc_endpwent)(void); 293 int (*_libc_initgroups)(const char *user, gid_t gid); 294 struct group *(*_libc_getgrnam)(const char *name); 295 int (*_libc_getgrnam_r)(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result); 296 struct group *(*_libc_getgrgid)(gid_t gid); 297 int (*_libc_getgrgid_r)(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result); 298 void (*_libc_setgrent)(void); 299 struct group *(*_libc_getgrent)(void); 300 #ifdef HAVE_SOLARIS_GETGRENT_R 301 struct group *(*_libc_getgrent_r)(struct group *group, char *buf, size_t buflen); 144 302 #else 145 #define NWRAP_VERBOSE(args) 303 int (*_libc_getgrent_r)(struct group *group, char *buf, size_t buflen, struct group **result); 146 304 #endif 305 void (*_libc_endgrent)(void); 306 int (*_libc_getgrouplist)(const char *user, gid_t group, gid_t *groups, int *ngroups); 307 308 void (*_libc_sethostent)(int stayopen); 309 struct hostent *(*_libc_gethostent)(void); 310 void (*_libc_endhostent)(void); 311 312 struct hostent *(*_libc_gethostbyname)(const char *name); 313 #ifdef HAVE_GETHOSTBYNAME2 /* GNU extension */ 314 struct hostent *(*_libc_gethostbyname2)(const char *name, int af); 315 #endif 316 struct hostent *(*_libc_gethostbyaddr)(const void *addr, socklen_t len, int type); 317 318 int (*_libc_getaddrinfo)(const char *node, const char *service, 319 const struct addrinfo *hints, 320 struct addrinfo **res); 321 int (*_libc_getnameinfo)(const struct sockaddr *sa, socklen_t salen, 322 char *host, size_t hostlen, 323 char *serv, size_t servlen, 324 int flags); 325 int (*_libc_gethostname)(char *name, size_t len); 326 #ifdef HAVE_GETHOSTBYNAME_R 327 int (*_libc_gethostbyname_r)(const char *name, 328 struct hostent *ret, 329 char *buf, size_t buflen, 330 struct hostent **result, int *h_errnop); 331 #endif 332 #ifdef HAVE_GETHOSTBYADDR_R 333 int (*_libc_gethostbyaddr_r)(const void *addr, socklen_t len, int type, 334 struct hostent *ret, 335 char *buf, size_t buflen, 336 struct hostent **result, int *h_errnop); 337 #endif 338 }; 147 339 148 340 struct nwrap_module_nss_fns { … … 212 404 }; 213 405 406 /* Public prototypes */ 407 408 bool nss_wrapper_enabled(void); 409 bool nss_wrapper_shadow_enabled(void); 410 bool nss_wrapper_hosts_enabled(void); 411 214 412 /* prototypes for files backend */ 215 413 … … 327 525 }; 328 526 527 struct nwrap_libc { 528 void *handle; 529 void *nsl_handle; 530 void *sock_handle; 531 struct nwrap_libc_fns *fns; 532 }; 533 329 534 struct nwrap_main { 330 const char *nwrap_switch;331 535 int num_backends; 332 536 struct nwrap_backend *backends; 537 struct nwrap_libc *libc; 333 538 }; 334 539 335 struct nwrap_main *nwrap_main_global; 336 struct nwrap_main __nwrap_main_global; 540 static struct nwrap_main *nwrap_main_global; 541 static struct nwrap_main __nwrap_main_global; 542 543 /* 544 * PROTOTYPES 545 */ 546 static int nwrap_convert_he_ai(const struct hostent *he, 547 unsigned short port, 548 const struct addrinfo *hints, 549 struct addrinfo **pai, 550 bool skip_canonname); 551 552 /* 553 * VECTORS 554 */ 555 556 #define DEFAULT_VECTOR_CAPACITY 16 557 558 struct nwrap_vector { 559 void **items; 560 size_t count; 561 size_t capacity; 562 }; 563 564 /* Macro returns pointer to first element of vector->items array. 565 * 566 * nwrap_vector is used as a memory backend which take care of 567 * memory allocations and other stuff like memory growing. 568 * nwrap_vectors should not be considered as some abstract structures. 569 * On this level, vectors are more handy than direct realloc/malloc 570 * calls. 571 * 572 * nwrap_vector->items is array inside nwrap_vector which can be 573 * directly pointed by libc structure assembled by cwrap itself. 574 * 575 * EXAMPLE: 576 * 577 * 1) struct hostent contains char **h_addr_list element. 578 * 2) nwrap_vector holds array of pointers to addresses. 579 * It's easier to use vector to store results of 580 * file parsing etc. 581 * 582 * Now, pretend that cwrap assembled struct hostent and 583 * we need to set h_addr_list to point to nwrap_vector. 584 * Idea behind is to shield users from internal nwrap_vector 585 * implementation. 586 * (Yes, not fully - array terminated by NULL is needed because 587 * it's result expected by libc function caller.) 588 * 589 * 590 * CODE EXAMPLE: 591 * 592 * struct hostent he; 593 * struct nwrap_vector *vector = malloc(sizeof(struct nwrap_vector)); 594 * ... don't care about failed allocation now ... 595 * 596 * ... fill nwrap vector ... 597 * 598 * struct hostent he; 599 * he.h_addr_list = nwrap_vector_head(vector); 600 * 601 */ 602 #define nwrap_vector_head(vect) ((void *)((vect)->items)) 603 604 #define nwrap_vector_foreach(item, vect, iter) \ 605 for (iter = 0, (item) = (vect).items == NULL ? NULL : (vect).items[0]; \ 606 item != NULL; \ 607 (item) = (vect).items[++iter]) 608 609 #define nwrap_vector_is_initialized(vector) ((vector)->items != NULL) 610 611 static inline bool nwrap_vector_init(struct nwrap_vector *const vector) 612 { 613 if (vector == NULL) { 614 return false; 615 } 616 617 /* count is initialized by ZERO_STRUCTP */ 618 ZERO_STRUCTP(vector); 619 vector->items = malloc(sizeof(void *) * (DEFAULT_VECTOR_CAPACITY + 1)); 620 if (vector->items == NULL) { 621 return false; 622 } 623 vector->capacity = DEFAULT_VECTOR_CAPACITY; 624 memset(vector->items, '\0', sizeof(void *) * (DEFAULT_VECTOR_CAPACITY + 1)); 625 626 return true; 627 } 628 629 static bool nwrap_vector_add_item(struct nwrap_vector *vector, void *const item) 630 { 631 assert (vector != NULL); 632 633 if (vector->items == NULL) { 634 nwrap_vector_init(vector); 635 } 636 637 if (vector->count == vector->capacity) { 638 /* Items array _MUST_ be NULL terminated because it's passed 639 * as result to caller which expect NULL terminated array from libc. 640 */ 641 void **items = realloc(vector->items, sizeof(void *) * ((vector->capacity * 2) + 1)); 642 if (items == NULL) { 643 return false; 644 } 645 vector->items = items; 646 647 /* Don't count ending NULL to capacity */ 648 vector->capacity *= 2; 649 } 650 651 vector->items[vector->count] = item; 652 653 vector->count += 1; 654 vector->items[vector->count] = NULL; 655 656 return true; 657 } 658 659 static bool nwrap_vector_merge(struct nwrap_vector *dst, 660 struct nwrap_vector *src) 661 { 662 void **dst_items = NULL; 663 size_t count; 664 665 if (src->count == 0) { 666 return true; 667 } 668 669 count = dst->count + src->count; 670 671 /* We don't need reallocation if we have enough capacity. */ 672 if (src->count > (dst->capacity - dst->count)) { 673 dst_items = (void **)realloc(dst->items, (count + 1) * sizeof(void *)); 674 if (dst_items == NULL) { 675 return false; 676 } 677 dst->items = dst_items; 678 dst->capacity = count; 679 } 680 681 memcpy((void *)(((long *)dst->items) + dst->count), 682 src->items, 683 src->count * sizeof(void *)); 684 dst->count = count; 685 686 return true; 687 } 337 688 338 689 struct nwrap_cache { 339 690 const char *path; 340 691 int fd; 692 FILE *fp; 341 693 struct stat st; 342 uint8_t *buf;343 694 void *private_data; 695 696 struct nwrap_vector lines; 697 344 698 bool (*parse_line)(struct nwrap_cache *, char *line); 345 699 void (*unload)(struct nwrap_cache *); 346 700 }; 347 701 702 /* passwd */ 348 703 struct nwrap_pw { 349 704 struct nwrap_cache *cache; … … 360 715 static void nwrap_pw_unload(struct nwrap_cache *nwrap); 361 716 717 /* shadow */ 718 #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) 719 struct nwrap_sp { 720 struct nwrap_cache *cache; 721 722 struct spwd *list; 723 int num; 724 int idx; 725 }; 726 727 struct nwrap_cache __nwrap_cache_sp; 728 struct nwrap_sp nwrap_sp_global; 729 730 static bool nwrap_sp_parse_line(struct nwrap_cache *nwrap, char *line); 731 static void nwrap_sp_unload(struct nwrap_cache *nwrap); 732 #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ 733 734 /* group */ 362 735 struct nwrap_gr { 363 736 struct nwrap_cache *cache; … … 371 744 struct nwrap_gr nwrap_gr_global; 372 745 746 /* hosts */ 747 static bool nwrap_he_parse_line(struct nwrap_cache *nwrap, char *line); 748 static void nwrap_he_unload(struct nwrap_cache *nwrap); 749 750 struct nwrap_addrdata { 751 unsigned char host_addr[16]; /* IPv4 or IPv6 address */ 752 }; 753 754 static size_t max_hostents = 100; 755 756 struct nwrap_entdata { 757 struct nwrap_addrdata addr; 758 struct hostent ht; 759 760 struct nwrap_vector nwrap_addrdata; 761 762 ssize_t aliases_count; 763 }; 764 765 struct nwrap_entlist { 766 struct nwrap_entlist *next; 767 struct nwrap_entdata *ed; 768 }; 769 770 struct nwrap_he { 771 struct nwrap_cache *cache; 772 773 struct nwrap_vector entries; 774 struct nwrap_vector lists; 775 776 int num; 777 int idx; 778 }; 779 780 static struct nwrap_cache __nwrap_cache_he; 781 static struct nwrap_he nwrap_he_global; 782 783 784 /********************************************************* 785 * NWRAP PROTOTYPES 786 *********************************************************/ 787 788 static void nwrap_init(void); 373 789 static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line); 374 790 static void nwrap_gr_unload(struct nwrap_cache *nwrap); 791 void nwrap_destructor(void) DESTRUCTOR_ATTRIBUTE; 792 793 /********************************************************* 794 * NWRAP LIBC LOADER FUNCTIONS 795 *********************************************************/ 796 797 enum nwrap_lib { 798 NWRAP_LIBC, 799 NWRAP_LIBNSL, 800 NWRAP_LIBSOCKET, 801 }; 802 803 #ifndef NDEBUG 804 static const char *nwrap_str_lib(enum nwrap_lib lib) 805 { 806 switch (lib) { 807 case NWRAP_LIBC: 808 return "libc"; 809 case NWRAP_LIBNSL: 810 return "libnsl"; 811 case NWRAP_LIBSOCKET: 812 return "libsocket"; 813 } 814 815 /* Compiler would warn us about unhandled enum value if we get here */ 816 return "unknown"; 817 } 818 #endif 819 820 static void *nwrap_load_lib_handle(enum nwrap_lib lib) 821 { 822 int flags = RTLD_LAZY; 823 void *handle = NULL; 824 int i; 825 826 #ifdef RTLD_DEEPBIND 827 flags |= RTLD_DEEPBIND; 828 #endif 829 830 switch (lib) { 831 case NWRAP_LIBNSL: 832 #ifdef HAVE_LIBNSL 833 handle = nwrap_main_global->libc->nsl_handle; 834 if (handle == NULL) { 835 for (i = 10; i >= 0; i--) { 836 char soname[256] = {0}; 837 838 snprintf(soname, sizeof(soname), "libnsl.so.%d", i); 839 handle = dlopen(soname, flags); 840 if (handle != NULL) { 841 break; 842 } 843 } 844 845 nwrap_main_global->libc->nsl_handle = handle; 846 } 847 break; 848 #endif 849 /* FALL TROUGH */ 850 case NWRAP_LIBSOCKET: 851 #ifdef HAVE_LIBSOCKET 852 handle = nwrap_main_global->libc->sock_handle; 853 if (handle == NULL) { 854 for (i = 10; i >= 0; i--) { 855 char soname[256] = {0}; 856 857 snprintf(soname, sizeof(soname), "libsocket.so.%d", i); 858 handle = dlopen(soname, flags); 859 if (handle != NULL) { 860 break; 861 } 862 } 863 864 nwrap_main_global->libc->sock_handle = handle; 865 } 866 break; 867 #endif 868 /* FALL TROUGH */ 869 case NWRAP_LIBC: 870 handle = nwrap_main_global->libc->handle; 871 if (handle == NULL) { 872 for (i = 10; i >= 0; i--) { 873 char soname[256] = {0}; 874 875 snprintf(soname, sizeof(soname), "libc.so.%d", i); 876 handle = dlopen(soname, flags); 877 if (handle != NULL) { 878 break; 879 } 880 } 881 882 nwrap_main_global->libc->handle = handle; 883 } 884 break; 885 } 886 887 if (handle == NULL) { 888 #ifdef RTLD_NEXT 889 handle = nwrap_main_global->libc->handle 890 = nwrap_main_global->libc->sock_handle 891 = nwrap_main_global->libc->nsl_handle 892 = RTLD_NEXT; 893 #else 894 NWRAP_LOG(NWRAP_LOG_ERROR, 895 "Failed to dlopen library: %s\n", 896 dlerror()); 897 exit(-1); 898 #endif 899 } 900 901 return handle; 902 } 903 904 static void *_nwrap_load_lib_function(enum nwrap_lib lib, const char *fn_name) 905 { 906 void *handle; 907 void *func; 908 909 nwrap_init(); 910 911 handle = nwrap_load_lib_handle(lib); 912 913 func = dlsym(handle, fn_name); 914 if (func == NULL) { 915 NWRAP_LOG(NWRAP_LOG_ERROR, 916 "Failed to find %s: %s\n", 917 fn_name, dlerror()); 918 exit(-1); 919 } 920 921 NWRAP_LOG(NWRAP_LOG_TRACE, 922 "Loaded %s from %s", 923 fn_name, nwrap_str_lib(lib)); 924 return func; 925 } 926 927 #define nwrap_load_lib_function(lib, fn_name) \ 928 if (nwrap_main_global->libc->fns->_libc_##fn_name == NULL) { \ 929 *(void **) (&nwrap_main_global->libc->fns->_libc_##fn_name) = \ 930 _nwrap_load_lib_function(lib, #fn_name); \ 931 } 932 933 /* INTERNAL HELPER FUNCTIONS */ 934 static void nwrap_lines_unload(struct nwrap_cache *const nwrap) 935 { 936 size_t p; 937 void *item; 938 nwrap_vector_foreach(item, nwrap->lines, p) { 939 /* Maybe some vectors were merged ... */ 940 SAFE_FREE(item); 941 } 942 SAFE_FREE(nwrap->lines.items); 943 ZERO_STRUCTP(&nwrap->lines); 944 } 945 946 /* 947 * IMPORTANT 948 * 949 * Functions expeciall from libc need to be loaded individually, you can't load 950 * all at once or gdb will segfault at startup. The same applies to valgrind and 951 * has probably something todo with with the linker. 952 * So we need load each function at the point it is called the first time. 953 */ 954 static struct passwd *libc_getpwnam(const char *name) 955 { 956 nwrap_load_lib_function(NWRAP_LIBC, getpwnam); 957 958 return nwrap_main_global->libc->fns->_libc_getpwnam(name); 959 } 960 961 #ifdef HAVE_GETPWNAM_R 962 static int libc_getpwnam_r(const char *name, 963 struct passwd *pwd, 964 char *buf, 965 size_t buflen, 966 struct passwd **result) 967 { 968 #ifdef HAVE___POSIX_GETPWNAM_R 969 if (nwrap_main_global->libc->fns->_libc_getpwnam_r == NULL) { 970 *(void **) (&nwrap_main_global->libc->fns->_libc_getpwnam_r) = 971 _nwrap_load_lib_function(NWRAP_LIBC, "__posix_getpwnam_r"); 972 } 973 #else 974 nwrap_load_lib_function(NWRAP_LIBC, getpwnam_r); 975 #endif 976 977 return nwrap_main_global->libc->fns->_libc_getpwnam_r(name, 978 pwd, 979 buf, 980 buflen, 981 result); 982 } 983 #endif 984 985 static struct passwd *libc_getpwuid(uid_t uid) 986 { 987 nwrap_load_lib_function(NWRAP_LIBC, getpwuid); 988 989 return nwrap_main_global->libc->fns->_libc_getpwuid(uid); 990 } 991 992 #ifdef HAVE_GETPWUID_R 993 static int libc_getpwuid_r(uid_t uid, 994 struct passwd *pwd, 995 char *buf, 996 size_t buflen, 997 struct passwd **result) 998 { 999 #ifdef HAVE___POSIX_GETPWUID_R 1000 if (nwrap_main_global->libc->fns->_libc_getpwuid_r == NULL) { 1001 *(void **) (&nwrap_main_global->libc->fns->_libc_getpwuid_r) = 1002 _nwrap_load_lib_function(NWRAP_LIBC, "__posix_getpwuid_r"); 1003 } 1004 #else 1005 nwrap_load_lib_function(NWRAP_LIBC, getpwuid_r); 1006 #endif 1007 1008 return nwrap_main_global->libc->fns->_libc_getpwuid_r(uid, 1009 pwd, 1010 buf, 1011 buflen, 1012 result); 1013 } 1014 #endif 1015 1016 static inline void str_tolower(char *dst, char *src) 1017 { 1018 register char *src_tmp = src; 1019 register char *dst_tmp = dst; 1020 1021 while (*src_tmp != '\0') { 1022 *dst_tmp = tolower(*src_tmp); 1023 ++src_tmp; 1024 ++dst_tmp; 1025 } 1026 } 1027 1028 static bool str_tolower_copy(char **dst_name, const char *const src_name) 1029 { 1030 char *h_name_lower; 1031 1032 if ((dst_name == NULL) || (src_name == NULL)) { 1033 return false; 1034 } 1035 1036 h_name_lower = strdup(src_name); 1037 if (h_name_lower == NULL) { 1038 NWRAP_LOG(NWRAP_LOG_DEBUG, "Out of memory while strdup"); 1039 return false; 1040 } 1041 1042 str_tolower(h_name_lower, h_name_lower); 1043 *dst_name = h_name_lower; 1044 return true; 1045 } 1046 1047 static void libc_setpwent(void) 1048 { 1049 nwrap_load_lib_function(NWRAP_LIBC, setpwent); 1050 1051 nwrap_main_global->libc->fns->_libc_setpwent(); 1052 } 1053 1054 static struct passwd *libc_getpwent(void) 1055 { 1056 nwrap_load_lib_function(NWRAP_LIBC, getpwent); 1057 1058 return nwrap_main_global->libc->fns->_libc_getpwent(); 1059 } 1060 1061 #ifdef HAVE_SOLARIS_GETPWENT_R 1062 static struct passwd *libc_getpwent_r(struct passwd *pwdst, 1063 char *buf, 1064 int buflen) 1065 { 1066 nwrap_load_lib_function(NWRAP_LIBC, getpwent_r); 1067 1068 return nwrap_main_global->libc->fns->_libc_getpwent_r(pwdst, 1069 buf, 1070 buflen); 1071 } 1072 #else /* HAVE_SOLARIS_GETPWENT_R */ 1073 static int libc_getpwent_r(struct passwd *pwdst, 1074 char *buf, 1075 size_t buflen, 1076 struct passwd **pwdstp) 1077 { 1078 nwrap_load_lib_function(NWRAP_LIBC, getpwent_r); 1079 1080 return nwrap_main_global->libc->fns->_libc_getpwent_r(pwdst, 1081 buf, 1082 buflen, 1083 pwdstp); 1084 } 1085 #endif /* HAVE_SOLARIS_GETPWENT_R */ 1086 1087 static void libc_endpwent(void) 1088 { 1089 nwrap_load_lib_function(NWRAP_LIBC, endpwent); 1090 1091 nwrap_main_global->libc->fns->_libc_endpwent(); 1092 } 1093 1094 static int libc_initgroups(const char *user, gid_t gid) 1095 { 1096 nwrap_load_lib_function(NWRAP_LIBC, initgroups); 1097 1098 return nwrap_main_global->libc->fns->_libc_initgroups(user, gid); 1099 } 1100 1101 static struct group *libc_getgrnam(const char *name) 1102 { 1103 nwrap_load_lib_function(NWRAP_LIBC, getgrnam); 1104 1105 return nwrap_main_global->libc->fns->_libc_getgrnam(name); 1106 } 1107 1108 #ifdef HAVE_GETGRNAM_R 1109 static int libc_getgrnam_r(const char *name, 1110 struct group *grp, 1111 char *buf, 1112 size_t buflen, 1113 struct group **result) 1114 { 1115 #ifdef HAVE___POSIX_GETGRNAM_R 1116 if (nwrap_main_global->libc->fns->_libc_getgrnam_r == NULL) { 1117 *(void **) (&nwrap_main_global->libc->fns->_libc_getgrnam_r) = 1118 _nwrap_load_lib_function(NWRAP_LIBC, "__posix_getgrnam_r"); 1119 } 1120 #else 1121 nwrap_load_lib_function(NWRAP_LIBC, getgrnam_r); 1122 #endif 1123 1124 return nwrap_main_global->libc->fns->_libc_getgrnam_r(name, 1125 grp, 1126 buf, 1127 buflen, 1128 result); 1129 } 1130 #endif 1131 1132 static struct group *libc_getgrgid(gid_t gid) 1133 { 1134 nwrap_load_lib_function(NWRAP_LIBC, getgrgid); 1135 1136 return nwrap_main_global->libc->fns->_libc_getgrgid(gid); 1137 } 1138 1139 #ifdef HAVE_GETGRGID_R 1140 static int libc_getgrgid_r(gid_t gid, 1141 struct group *grp, 1142 char *buf, 1143 size_t buflen, 1144 struct group **result) 1145 { 1146 #ifdef HAVE___POSIX_GETGRGID_R 1147 if (nwrap_main_global->libc->fns->_libc_getgrgid_r == NULL) { 1148 *(void **) (&nwrap_main_global->libc->fns->_libc_getgrgid_r) = 1149 _nwrap_load_lib_function(NWRAP_LIBC, "__posix_getgrgid_r"); 1150 } 1151 #else 1152 nwrap_load_lib_function(NWRAP_LIBC, getgrgid_r); 1153 #endif 1154 1155 return nwrap_main_global->libc->fns->_libc_getgrgid_r(gid, 1156 grp, 1157 buf, 1158 buflen, 1159 result); 1160 } 1161 #endif 1162 1163 static void libc_setgrent(void) 1164 { 1165 nwrap_load_lib_function(NWRAP_LIBC, setgrent); 1166 1167 nwrap_main_global->libc->fns->_libc_setgrent(); 1168 } 1169 1170 static struct group *libc_getgrent(void) 1171 { 1172 nwrap_load_lib_function(NWRAP_LIBC, getgrent); 1173 1174 return nwrap_main_global->libc->fns->_libc_getgrent(); 1175 } 1176 1177 #ifdef HAVE_GETGRENT_R 1178 #ifdef HAVE_SOLARIS_GETGRENT_R 1179 static struct group *libc_getgrent_r(struct group *group, 1180 char *buf, 1181 size_t buflen) 1182 { 1183 nwrap_load_lib_function(NWRAP_LIBC, getgrent_r); 1184 1185 return nwrap_main_global->libc->fns->_libc_getgrent_r(group, 1186 buf, 1187 buflen); 1188 } 1189 #else /* !HAVE_SOLARIS_GETGRENT_R */ 1190 static int libc_getgrent_r(struct group *group, 1191 char *buf, 1192 size_t buflen, 1193 struct group **result) 1194 { 1195 nwrap_load_lib_function(NWRAP_LIBC, getgrent_r); 1196 1197 return nwrap_main_global->libc->fns->_libc_getgrent_r(group, 1198 buf, 1199 buflen, 1200 result); 1201 } 1202 #endif /* HAVE_SOLARIS_GETGRENT_R */ 1203 #endif /* HAVE_GETGRENT_R */ 1204 1205 static void libc_endgrent(void) 1206 { 1207 nwrap_load_lib_function(NWRAP_LIBC, endgrent); 1208 1209 nwrap_main_global->libc->fns->_libc_endgrent(); 1210 } 1211 1212 #ifdef HAVE_GETGROUPLIST 1213 static int libc_getgrouplist(const char *user, 1214 gid_t group, 1215 gid_t *groups, 1216 int *ngroups) 1217 { 1218 nwrap_load_lib_function(NWRAP_LIBC, getgrouplist); 1219 1220 return nwrap_main_global->libc->fns->_libc_getgrouplist(user, 1221 group, 1222 groups, 1223 ngroups); 1224 } 1225 #endif 1226 1227 static void libc_sethostent(int stayopen) 1228 { 1229 nwrap_load_lib_function(NWRAP_LIBNSL, sethostent); 1230 1231 nwrap_main_global->libc->fns->_libc_sethostent(stayopen); 1232 } 1233 1234 static struct hostent *libc_gethostent(void) 1235 { 1236 nwrap_load_lib_function(NWRAP_LIBNSL, gethostent); 1237 1238 return nwrap_main_global->libc->fns->_libc_gethostent(); 1239 } 1240 1241 static void libc_endhostent(void) 1242 { 1243 nwrap_load_lib_function(NWRAP_LIBNSL, endhostent); 1244 1245 nwrap_main_global->libc->fns->_libc_endhostent(); 1246 } 1247 1248 static struct hostent *libc_gethostbyname(const char *name) 1249 { 1250 nwrap_load_lib_function(NWRAP_LIBNSL, gethostbyname); 1251 1252 return nwrap_main_global->libc->fns->_libc_gethostbyname(name); 1253 } 1254 1255 #ifdef HAVE_GETHOSTBYNAME2 /* GNU extension */ 1256 static struct hostent *libc_gethostbyname2(const char *name, int af) 1257 { 1258 nwrap_load_lib_function(NWRAP_LIBNSL, gethostbyname2); 1259 1260 return nwrap_main_global->libc->fns->_libc_gethostbyname2(name, af); 1261 } 1262 #endif 1263 1264 static struct hostent *libc_gethostbyaddr(const void *addr, 1265 socklen_t len, 1266 int type) 1267 { 1268 nwrap_load_lib_function(NWRAP_LIBNSL, gethostbyaddr); 1269 1270 return nwrap_main_global->libc->fns->_libc_gethostbyaddr(addr, 1271 len, 1272 type); 1273 } 1274 1275 static int libc_gethostname(char *name, size_t len) 1276 { 1277 nwrap_load_lib_function(NWRAP_LIBNSL, gethostname); 1278 1279 return nwrap_main_global->libc->fns->_libc_gethostname(name, len); 1280 } 1281 1282 #ifdef HAVE_GETHOSTBYNAME_R 1283 static int libc_gethostbyname_r(const char *name, 1284 struct hostent *ret, 1285 char *buf, 1286 size_t buflen, 1287 struct hostent **result, 1288 int *h_errnop) 1289 { 1290 nwrap_load_lib_function(NWRAP_LIBNSL, gethostbyname_r); 1291 1292 return nwrap_main_global->libc->fns->_libc_gethostbyname_r(name, 1293 ret, 1294 buf, 1295 buflen, 1296 result, 1297 h_errnop); 1298 } 1299 #endif 1300 1301 #ifdef HAVE_GETHOSTBYADDR_R 1302 static int libc_gethostbyaddr_r(const void *addr, 1303 socklen_t len, 1304 int type, 1305 struct hostent *ret, 1306 char *buf, 1307 size_t buflen, 1308 struct hostent **result, 1309 int *h_errnop) 1310 { 1311 nwrap_load_lib_function(NWRAP_LIBNSL, gethostbyaddr_r); 1312 1313 return nwrap_main_global->libc->fns->_libc_gethostbyaddr_r(addr, 1314 len, 1315 type, 1316 ret, 1317 buf, 1318 buflen, 1319 result, 1320 h_errnop); 1321 } 1322 #endif 1323 1324 static int libc_getaddrinfo(const char *node, 1325 const char *service, 1326 const struct addrinfo *hints, 1327 struct addrinfo **res) 1328 { 1329 nwrap_load_lib_function(NWRAP_LIBSOCKET, getaddrinfo); 1330 1331 return nwrap_main_global->libc->fns->_libc_getaddrinfo(node, 1332 service, 1333 hints, 1334 res); 1335 } 1336 1337 static int libc_getnameinfo(const struct sockaddr *sa, 1338 socklen_t salen, 1339 char *host, 1340 size_t hostlen, 1341 char *serv, 1342 size_t servlen, 1343 int flags) 1344 { 1345 nwrap_load_lib_function(NWRAP_LIBSOCKET, getnameinfo); 1346 1347 return nwrap_main_global->libc->fns->_libc_getnameinfo(sa, 1348 salen, 1349 host, 1350 hostlen, 1351 serv, 1352 servlen, 1353 flags); 1354 } 1355 1356 /********************************************************* 1357 * NWRAP NSS MODULE LOADER FUNCTIONS 1358 *********************************************************/ 375 1359 376 1360 static void *nwrap_load_module_fn(struct nwrap_backend *b, … … 381 1365 382 1366 if (!b->so_handle) { 383 NWRAP_ERROR(("%s: no handle\n", 384 __location__)); 1367 NWRAP_LOG(NWRAP_LOG_ERROR, "No handle"); 385 1368 return NULL; 386 1369 } 387 1370 388 1371 if (asprintf(&s, "_nss_%s_%s", b->name, fn_name) == -1) { 389 NWRAP_ERROR(("%s: out of memory\n", 390 __location__)); 1372 NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory"); 391 1373 return NULL; 392 1374 } … … 394 1376 res = dlsym(b->so_handle, s); 395 1377 if (!res) { 396 NWRAP_ ERROR(("%s: cannot find function %s in %s\n",397 __location__, s, b->so_path));398 }399 free(s);400 s = NULL;1378 NWRAP_LOG(NWRAP_LOG_ERROR, 1379 "Cannot find function %s in %s", 1380 s, b->so_path); 1381 } 1382 SAFE_FREE(s); 401 1383 return res; 402 1384 } … … 415 1397 } 416 1398 417 fns->_nss_getpwnam_r = (NSS_STATUS (*)(const char *, struct passwd *, char *, size_t, int *))418 419 fns->_nss_getpwuid_r = (NSS_STATUS (*)(uid_t, struct passwd *, char *, size_t, int *))420 421 fns->_nss_setpwent = (NSS_STATUS(*)(void))422 423 fns->_nss_getpwent_r = (NSS_STATUS (*)(struct passwd *, char *, size_t, int *))424 425 fns->_nss_endpwent = (NSS_STATUS(*)(void))426 427 fns->_nss_initgroups = (NSS_STATUS (*)(const char *, gid_t, long int *, long int *, gid_t **, long int, int *))428 429 fns->_nss_getgrnam_r = (NSS_STATUS (*)(const char *, struct group *, char *, size_t, int *))430 431 fns->_nss_getgrgid_r = (NSS_STATUS (*)(gid_t, struct group *, char *, size_t, int *))432 433 fns->_nss_setgrent = (NSS_STATUS(*)(void))434 435 fns->_nss_getgrent_r = (NSS_STATUS (*)(struct group *, char *, size_t, int *))436 437 fns->_nss_endgrent = (NSS_STATUS(*)(void))438 1399 *(void **)(&fns->_nss_getpwnam_r) = 1400 nwrap_load_module_fn(b, "getpwnam_r"); 1401 *(void **)(&fns->_nss_getpwuid_r) = 1402 nwrap_load_module_fn(b, "getpwuid_r"); 1403 *(void **)(&fns->_nss_setpwent) = 1404 nwrap_load_module_fn(b, "setpwent"); 1405 *(void **)(&fns->_nss_getpwent_r) = 1406 nwrap_load_module_fn(b, "getpwent_r"); 1407 *(void **)(&fns->_nss_endpwent) = 1408 nwrap_load_module_fn(b, "endpwent"); 1409 *(void **)(&fns->_nss_initgroups) = 1410 nwrap_load_module_fn(b, "initgroups_dyn"); 1411 *(void **)(&fns->_nss_getgrnam_r) = 1412 nwrap_load_module_fn(b, "getgrnam_r"); 1413 *(void **)(&fns->_nss_getgrgid_r)= 1414 nwrap_load_module_fn(b, "getgrgid_r"); 1415 *(void **)(&fns->_nss_setgrent) = 1416 nwrap_load_module_fn(b, "setgrent"); 1417 *(void **)(&fns->_nss_getgrent_r) = 1418 nwrap_load_module_fn(b, "getgrent_r"); 1419 *(void **)(&fns->_nss_endgrent) = 1420 nwrap_load_module_fn(b, "endgrent"); 439 1421 440 1422 return fns; … … 451 1433 h = dlopen(so_path, RTLD_LAZY); 452 1434 if (!h) { 453 NWRAP_ERROR(("%s: cannot open shared library %s\n", 454 __location__, so_path)); 1435 NWRAP_LOG(NWRAP_LOG_ERROR, 1436 "Cannot open shared library %s", 1437 so_path); 455 1438 return NULL; 456 1439 } … … 470 1453 sizeof(struct nwrap_backend) * ((*num_backends) + 1)); 471 1454 if (!*backends) { 472 NWRAP_ERROR(("%s: out of memory\n", 473 __location__)); 1455 NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory"); 474 1456 return false; 475 1457 } … … 497 1479 } 498 1480 1481 static void nwrap_libc_init(struct nwrap_main *r) 1482 { 1483 r->libc = malloc(sizeof(struct nwrap_libc)); 1484 if (r->libc == NULL) { 1485 printf("Failed to allocate memory for libc"); 1486 exit(-1); 1487 } 1488 ZERO_STRUCTP(r->libc); 1489 1490 r->libc->fns = malloc(sizeof(struct nwrap_libc_fns)); 1491 if (r->libc->fns == NULL) { 1492 printf("Failed to allocate memory for libc functions"); 1493 exit(-1); 1494 } 1495 ZERO_STRUCTP(r->libc->fns); 1496 } 1497 499 1498 static void nwrap_backend_init(struct nwrap_main *r) 500 1499 { 501 const char *winbind_so_path = getenv("NSS_WRAPPER_WINBIND_SO_PATH"); 1500 const char *module_so_path = getenv("NSS_WRAPPER_MODULE_SO_PATH"); 1501 const char *module_fn_name = getenv("NSS_WRAPPER_MODULE_FN_PREFIX"); 502 1502 503 1503 r->num_backends = 0; … … 507 1507 &r->num_backends, 508 1508 &r->backends)) { 509 NWRAP_ ERROR(("%s: failed to initialize 'files' backend\n",510 __location__));1509 NWRAP_LOG(NWRAP_LOG_ERROR, 1510 "Failed to initialize 'files' backend"); 511 1511 return; 512 1512 } 513 1513 514 if (winbind_so_path && strlen(winbind_so_path)) { 515 if (!nwrap_module_init("winbind", &nwrap_module_ops, winbind_so_path, 1514 if (module_so_path != NULL && 1515 module_so_path[0] != '\0' && 1516 module_fn_name != NULL && 1517 module_fn_name[0] != '\0') { 1518 if (!nwrap_module_init(module_fn_name, 1519 &nwrap_module_ops, 1520 module_so_path, 516 1521 &r->num_backends, 517 1522 &r->backends)) { 518 NWRAP_ERROR(("%s: failed to initialize 'winbind' backend\n", 519 __location__)); 1523 NWRAP_LOG(NWRAP_LOG_ERROR, 1524 "Failed to initialize '%s' backend", 1525 module_fn_name); 520 1526 return; 521 1527 } … … 525 1531 static void nwrap_init(void) 526 1532 { 527 static bool initialized; 528 529 if (initialized) return; 530 initialized = true; 1533 const char *env; 1534 char *endptr; 1535 size_t max_hostents_tmp; 1536 1537 NWRAP_LOCK(nwrap_initialized); 1538 if (nwrap_initialized) { 1539 NWRAP_UNLOCK(nwrap_initialized); 1540 return; 1541 } 1542 1543 /* 1544 * Still holding nwrap_initialized lock here. 1545 * We don't use NWRAP_(UN)LOCK_ALL macros here because we 1546 * want to avoid overhead when other threads do their job. 1547 */ 1548 NWRAP_LOCK(nwrap_global); 1549 NWRAP_LOCK(nwrap_gr_global); 1550 NWRAP_LOCK(nwrap_he_global); 1551 NWRAP_LOCK(nwrap_pw_global); 1552 NWRAP_LOCK(nwrap_sp_global); 1553 1554 nwrap_initialized = true; 1555 1556 /* Initialize pthread_atfork handlers */ 1557 pthread_atfork(&nwrap_thread_prepare, &nwrap_thread_parent, 1558 &nwrap_thread_child); 1559 1560 env = getenv("NSS_WRAPPER_MAX_HOSTENTS"); 1561 if (env != NULL) { 1562 max_hostents_tmp = (size_t)strtol(env, &endptr, 10); 1563 if (((env != '\0') && (endptr == '\0')) || 1564 (max_hostents_tmp == 0)) { 1565 NWRAP_LOG(NWRAP_LOG_DEBUG, 1566 "Error parsing NSS_WRAPPER_MAX_HOSTENTS " 1567 "value or value is too small. " 1568 "Using default value: %lu.", 1569 (unsigned long)max_hostents); 1570 } else { 1571 max_hostents = max_hostents_tmp; 1572 } 1573 } 1574 /* Initialize hash table */ 1575 NWRAP_LOG(NWRAP_LOG_DEBUG, 1576 "Initializing hash table of size %lu items.", 1577 (unsigned long)max_hostents); 1578 if (hcreate(max_hostents) == 0) { 1579 NWRAP_LOG(NWRAP_LOG_ERROR, 1580 "Failed to initialize hash table"); 1581 goto done; 1582 } 531 1583 532 1584 nwrap_main_global = &__nwrap_main_global; 533 1585 1586 nwrap_libc_init(nwrap_main_global); 1587 534 1588 nwrap_backend_init(nwrap_main_global); 535 1589 1590 /* passwd */ 536 1591 nwrap_pw_global.cache = &__nwrap_cache_pw; 537 1592 538 1593 nwrap_pw_global.cache->path = getenv("NSS_WRAPPER_PASSWD"); 1594 nwrap_pw_global.cache->fp = NULL; 539 1595 nwrap_pw_global.cache->fd = -1; 540 1596 nwrap_pw_global.cache->private_data = &nwrap_pw_global; … … 542 1598 nwrap_pw_global.cache->unload = nwrap_pw_unload; 543 1599 1600 /* shadow */ 1601 #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) 1602 nwrap_sp_global.cache = &__nwrap_cache_sp; 1603 1604 nwrap_sp_global.cache->path = getenv("NSS_WRAPPER_SHADOW"); 1605 nwrap_sp_global.cache->fp = NULL; 1606 nwrap_sp_global.cache->fd = -1; 1607 nwrap_sp_global.cache->private_data = &nwrap_sp_global; 1608 nwrap_sp_global.cache->parse_line = nwrap_sp_parse_line; 1609 nwrap_sp_global.cache->unload = nwrap_sp_unload; 1610 #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ 1611 1612 /* group */ 544 1613 nwrap_gr_global.cache = &__nwrap_cache_gr; 545 1614 546 1615 nwrap_gr_global.cache->path = getenv("NSS_WRAPPER_GROUP"); 1616 nwrap_gr_global.cache->fp = NULL; 547 1617 nwrap_gr_global.cache->fd = -1; 548 1618 nwrap_gr_global.cache->private_data = &nwrap_gr_global; 549 1619 nwrap_gr_global.cache->parse_line = nwrap_gr_parse_line; 550 1620 nwrap_gr_global.cache->unload = nwrap_gr_unload; 551 } 552 553 static bool nwrap_enabled(void) 1621 1622 /* hosts */ 1623 nwrap_he_global.cache = &__nwrap_cache_he; 1624 1625 nwrap_he_global.cache->path = getenv("NSS_WRAPPER_HOSTS"); 1626 nwrap_he_global.cache->fp = NULL; 1627 nwrap_he_global.cache->fd = -1; 1628 nwrap_he_global.cache->private_data = &nwrap_he_global; 1629 nwrap_he_global.cache->parse_line = nwrap_he_parse_line; 1630 nwrap_he_global.cache->unload = nwrap_he_unload; 1631 1632 done: 1633 /* We hold all locks here so we can use NWRAP_UNLOCK_ALL. */ 1634 NWRAP_UNLOCK_ALL; 1635 } 1636 1637 bool nss_wrapper_enabled(void) 554 1638 { 555 1639 nwrap_init(); 556 1640 557 if (!nwrap_pw_global.cache->path) { 1641 if (nwrap_pw_global.cache->path == NULL || 1642 nwrap_pw_global.cache->path[0] == '\0') { 558 1643 return false; 559 1644 } 560 if (nwrap_pw_global.cache->path[0] == '\0') { 1645 if (nwrap_gr_global.cache->path == NULL || 1646 nwrap_gr_global.cache->path[0] == '\0') { 561 1647 return false; 562 1648 } 563 if (!nwrap_gr_global.cache->path) { 1649 1650 return true; 1651 } 1652 1653 #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) 1654 bool nss_wrapper_shadow_enabled(void) 1655 { 1656 nwrap_init(); 1657 1658 if (nwrap_sp_global.cache->path == NULL || 1659 nwrap_sp_global.cache->path[0] == '\0') { 564 1660 return false; 565 1661 } 566 if (nwrap_gr_global.cache->path[0] == '\0') { 1662 1663 return true; 1664 } 1665 #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ 1666 1667 bool nss_wrapper_hosts_enabled(void) 1668 { 1669 nwrap_init(); 1670 1671 if (nwrap_he_global.cache->path == NULL || 1672 nwrap_he_global.cache->path[0] == '\0') { 567 1673 return false; 568 1674 } … … 571 1677 } 572 1678 1679 static bool nwrap_hostname_enabled(void) 1680 { 1681 nwrap_init(); 1682 1683 if (getenv("NSS_WRAPPER_HOSTNAME") == NULL) { 1684 return false; 1685 } 1686 1687 return true; 1688 } 1689 573 1690 static bool nwrap_parse_file(struct nwrap_cache *nwrap) 574 1691 { 575 int ret; 576 uint8_t *buf = NULL; 577 char *nline; 1692 char *line = NULL; 1693 ssize_t n; 1694 /* Unused but getline needs it */ 1695 size_t len; 1696 bool ok; 578 1697 579 1698 if (nwrap->st.st_size == 0) { 580 NWRAP_ DEBUG(("%s: size == 0\n",581 __location__));582 goto done;583 } 584 1699 NWRAP_LOG(NWRAP_LOG_DEBUG, "size == 0"); 1700 return true; 1701 } 1702 1703 /* Support for 32-bit system I guess */ 585 1704 if (nwrap->st.st_size > INT32_MAX) { 586 NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n", 587 __location__, (unsigned)nwrap->st.st_size)); 588 goto failed; 589 } 590 591 ret = lseek(nwrap->fd, 0, SEEK_SET); 592 if (ret != 0) { 593 NWRAP_ERROR(("%s: lseek - %d\n",__location__,ret)); 594 goto failed; 595 } 596 597 buf = (uint8_t *)malloc(nwrap->st.st_size + 1); 598 if (!buf) { 599 NWRAP_ERROR(("%s: malloc failed\n",__location__)); 600 goto failed; 601 } 602 603 ret = read(nwrap->fd, buf, nwrap->st.st_size); 604 if (ret != nwrap->st.st_size) { 605 NWRAP_ERROR(("%s: read(%u) gave %d\n", 606 __location__, (unsigned)nwrap->st.st_size, ret)); 607 goto failed; 608 } 609 610 buf[nwrap->st.st_size] = '\0'; 611 612 nline = (char *)buf; 613 while (nline && nline[0]) { 614 char *line; 615 char *e; 616 bool ok; 617 618 line = nline; 619 nline = NULL; 620 621 e = strchr(line, '\n'); 622 if (e) { 623 e[0] = '\0'; 624 e++; 625 if (e[0] == '\r') { 626 e[0] = '\0'; 627 e++; 1705 NWRAP_LOG(NWRAP_LOG_ERROR, 1706 "Size[%u] larger than INT32_MAX", 1707 (unsigned)nwrap->st.st_size); 1708 return false; 1709 } 1710 1711 rewind(nwrap->fp); 1712 1713 do { 1714 n = getline(&line, &len, nwrap->fp); 1715 if (n < 0) { 1716 SAFE_FREE(line); 1717 if (feof(nwrap->fp)) { 1718 break; 628 1719 } 629 nline = e; 630 } 631 632 NWRAP_VERBOSE(("%s:'%s'\n",__location__, line)); 633 634 if (strlen(line) == 0) { 1720 1721 NWRAP_LOG(NWRAP_LOG_ERROR, 1722 "Unable to read line from file: %s", 1723 nwrap->path); 1724 return false; 1725 } 1726 1727 if (line[n - 1] == '\n') { 1728 line[n - 1] = '\0'; 1729 } 1730 1731 if (line[0] == '\0') { 1732 SAFE_FREE(line); 635 1733 continue; 636 1734 } … … 638 1736 ok = nwrap->parse_line(nwrap, line); 639 1737 if (!ok) { 640 goto failed; 641 } 642 } 643 644 done: 645 nwrap->buf = buf; 1738 NWRAP_LOG(NWRAP_LOG_ERROR, 1739 "Unable to parse line file: %s", 1740 line); 1741 SAFE_FREE(line); 1742 return false; 1743 } 1744 1745 /* Line is parsed without issues so add it to list */ 1746 ok = nwrap_vector_add_item(&(nwrap->lines), (void *const) line); 1747 if (!ok) { 1748 NWRAP_LOG(NWRAP_LOG_ERROR, 1749 "Unable to add line to vector"); 1750 return false; 1751 } 1752 1753 /* This forces getline to allocate new memory for line. */ 1754 line = NULL; 1755 } while (!feof(nwrap->fp)); 1756 646 1757 return true; 647 648 failed:649 if (buf) free(buf);650 return false;651 1758 } 652 1759 … … 655 1762 nwrap->unload(nwrap); 656 1763 657 if (nwrap->buf) free(nwrap->buf); 658 659 nwrap->buf = NULL; 660 } 661 662 static void nwrap_files_cache_reload(struct nwrap_cache *nwrap) 1764 nwrap_lines_unload(nwrap); 1765 } 1766 1767 static bool nwrap_files_cache_reload(struct nwrap_cache *nwrap) 663 1768 { 664 1769 struct stat st; … … 667 1772 bool retried = false; 668 1773 1774 assert(nwrap != NULL); 1775 669 1776 reopen: 670 1777 if (nwrap->fd < 0) { 671 nwrap->fd = open(nwrap->path, O_RDONLY); 672 if (nwrap->fd < 0) { 673 NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n", 674 __location__, 675 nwrap->path, nwrap->fd, 676 strerror(errno))); 677 return; 678 } 679 NWRAP_VERBOSE(("%s: open '%s'\n", __location__, nwrap->path)); 1778 nwrap->fp = fopen(nwrap->path, "re"); 1779 if (nwrap->fp == NULL) { 1780 nwrap->fd = -1; 1781 NWRAP_LOG(NWRAP_LOG_ERROR, 1782 "Unable to open '%s' readonly %d:%s", 1783 nwrap->path, nwrap->fd, 1784 strerror(errno)); 1785 return false; 1786 1787 } 1788 nwrap->fd = fileno(nwrap->fp); 1789 NWRAP_LOG(NWRAP_LOG_DEBUG, "Open '%s'", nwrap->path); 680 1790 } 681 1791 682 1792 ret = fstat(nwrap->fd, &st); 683 1793 if (ret != 0) { 684 NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n", 685 __location__, 686 nwrap->path, 687 ret, strerror(errno))); 688 return; 1794 NWRAP_LOG(NWRAP_LOG_ERROR, 1795 "fstat(%s) - %d:%s", 1796 nwrap->path, 1797 ret, 1798 strerror(errno)); 1799 fclose(nwrap->fp); 1800 nwrap->fp = NULL; 1801 nwrap->fd = -1; 1802 return false; 689 1803 } 690 1804 691 1805 if (retried == false && st.st_nlink == 0) { 692 1806 /* maybe someone has replaced the file... */ 693 NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n", 694 __location__, nwrap->path)); 1807 NWRAP_LOG(NWRAP_LOG_TRACE, 1808 "st_nlink == 0, reopen %s", 1809 nwrap->path); 695 1810 retried = true; 696 1811 memset(&nwrap->st, 0, sizeof(nwrap->st)); 697 close(nwrap->fd); 1812 fclose(nwrap->fp); 1813 nwrap->fp = NULL; 698 1814 nwrap->fd = -1; 699 1815 goto reopen; … … 701 1817 702 1818 if (st.st_mtime == nwrap->st.st_mtime) { 703 NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n", 704 __location__, (unsigned)st.st_mtime)); 705 return; 706 } 707 NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n", 708 __location__, (unsigned)st.st_mtime, 709 (unsigned)nwrap->st.st_mtime)); 1819 NWRAP_LOG(NWRAP_LOG_TRACE, 1820 "st_mtime[%u] hasn't changed, skip reload", 1821 (unsigned)st.st_mtime); 1822 return true; 1823 } 1824 1825 NWRAP_LOG(NWRAP_LOG_TRACE, 1826 "st_mtime has changed [%u] => [%u], start reload", 1827 (unsigned)st.st_mtime, 1828 (unsigned)nwrap->st.st_mtime); 710 1829 711 1830 nwrap->st = st; … … 715 1834 ok = nwrap_parse_file(nwrap); 716 1835 if (!ok) { 717 NWRAP_ERROR(("%s: failed to reload %s\n", 718 __location__, nwrap->path)); 1836 NWRAP_LOG(NWRAP_LOG_ERROR, "Failed to reload %s", nwrap->path); 719 1837 nwrap_files_cache_unload(nwrap); 720 } 721 NWRAP_DEBUG(("%s: reloaded %s\n", 722 __location__, nwrap->path)); 1838 return false; 1839 } 1840 1841 NWRAP_LOG(NWRAP_LOG_TRACE, "Reloaded %s", nwrap->path); 1842 return true; 723 1843 } 724 1844 … … 740 1860 pw = (struct passwd *)realloc(nwrap_pw->list, list_size); 741 1861 if (!pw) { 742 NWRAP_ERROR(("%s:realloc(%u) failed\n", 743 __location__, list_size)); 1862 NWRAP_LOG(NWRAP_LOG_ERROR, 1863 "realloc(%u) failed", 1864 (unsigned)list_size); 744 1865 return false; 745 1866 } … … 753 1874 p = strchr(c, ':'); 754 1875 if (!p) { 755 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", 756 __location__, line, c)); 1876 NWRAP_LOG(NWRAP_LOG_ERROR, 1877 "Invalid line[%s]: '%s'", 1878 line, 1879 c); 757 1880 return false; 758 1881 } … … 762 1885 c = p; 763 1886 764 NWRAP_ VERBOSE(("name[%s]\n", pw->pw_name));1887 NWRAP_LOG(NWRAP_LOG_TRACE, "name[%s]\n", pw->pw_name); 765 1888 766 1889 /* password */ 767 1890 p = strchr(c, ':'); 768 1891 if (!p) { 769 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", 770 __location__, line, c)); 1892 NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); 771 1893 return false; 772 1894 } … … 776 1898 c = p; 777 1899 778 NWRAP_ VERBOSE(("password[%s]\n", pw->pw_passwd));1900 NWRAP_LOG(NWRAP_LOG_TRACE, "password[%s]\n", pw->pw_passwd); 779 1901 780 1902 /* uid */ 781 1903 p = strchr(c, ':'); 782 1904 if (!p) { 783 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", 784 __location__, line, c)); 1905 NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); 785 1906 return false; 786 1907 } … … 790 1911 pw->pw_uid = (uid_t)strtoul(c, &e, 10); 791 1912 if (c == e) { 792 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", 793 __location__, line, c, strerror(errno))); 1913 NWRAP_LOG(NWRAP_LOG_ERROR, 1914 "Invalid line[%s]: '%s' - %s", 1915 line, c, strerror(errno)); 794 1916 return false; 795 1917 } 796 1918 if (e == NULL) { 797 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", 798 __location__, line, c, strerror(errno))); 1919 NWRAP_LOG(NWRAP_LOG_ERROR, 1920 "Invalid line[%s]: '%s' - %s", 1921 line, c, strerror(errno)); 799 1922 return false; 800 1923 } 801 1924 if (e[0] != '\0') { 802 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", 803 __location__, line, c, strerror(errno))); 1925 NWRAP_LOG(NWRAP_LOG_ERROR, 1926 "Invalid line[%s]: '%s' - %s", 1927 line, c, strerror(errno)); 804 1928 return false; 805 1929 } 806 1930 c = p; 807 1931 808 NWRAP_ VERBOSE(("uid[%u]\n", pw->pw_uid));1932 NWRAP_LOG(NWRAP_LOG_TRACE, "uid[%u]", pw->pw_uid); 809 1933 810 1934 /* gid */ 811 1935 p = strchr(c, ':'); 812 1936 if (!p) { 813 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", 814 __location__, line, c)); 1937 NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); 815 1938 return false; 816 1939 } … … 820 1943 pw->pw_gid = (gid_t)strtoul(c, &e, 10); 821 1944 if (c == e) { 822 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", 823 __location__, line, c, strerror(errno))); 1945 NWRAP_LOG(NWRAP_LOG_ERROR, 1946 "Invalid line[%s]: '%s' - %s", 1947 line, c, strerror(errno)); 824 1948 return false; 825 1949 } 826 1950 if (e == NULL) { 827 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", 828 __location__, line, c, strerror(errno))); 1951 NWRAP_LOG(NWRAP_LOG_ERROR, 1952 "Invalid line[%s]: '%s' - %s", 1953 line, c, strerror(errno)); 829 1954 return false; 830 1955 } 831 1956 if (e[0] != '\0') { 832 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", 833 __location__, line, c, strerror(errno))); 1957 NWRAP_LOG(NWRAP_LOG_ERROR, 1958 "Invalid line[%s]: '%s' - %s", 1959 line, c, strerror(errno)); 834 1960 return false; 835 1961 } 836 1962 c = p; 837 1963 838 NWRAP_ VERBOSE(("gid[%u]\n", pw->pw_gid));1964 NWRAP_LOG(NWRAP_LOG_TRACE, "gid[%u]\n", pw->pw_gid); 839 1965 840 1966 /* gecos */ 841 1967 p = strchr(c, ':'); 842 1968 if (!p) { 843 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", 844 __location__, line, c)); 1969 NWRAP_LOG(NWRAP_LOG_ERROR, "invalid line[%s]: '%s'", line, c); 845 1970 return false; 846 1971 } … … 850 1975 c = p; 851 1976 852 NWRAP_ VERBOSE(("gecos[%s]\n", pw->pw_gecos));1977 NWRAP_LOG(NWRAP_LOG_TRACE, "gecos[%s]", pw->pw_gecos); 853 1978 854 1979 /* dir */ 855 1980 p = strchr(c, ':'); 856 1981 if (!p) { 857 NWRAP_ ERROR(("%s:'%s'\n",__location__,c));1982 NWRAP_LOG(NWRAP_LOG_ERROR, "'%s'", c); 858 1983 return false; 859 1984 } … … 863 1988 c = p; 864 1989 865 NWRAP_ VERBOSE(("dir[%s]\n", pw->pw_dir));1990 NWRAP_LOG(NWRAP_LOG_TRACE, "dir[%s]", pw->pw_dir); 866 1991 867 1992 /* shell */ 868 1993 pw->pw_shell = c; 869 NWRAP_VERBOSE(("shell[%s]\n", pw->pw_shell)); 870 871 NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n", 872 pw->pw_name, pw->pw_passwd, 873 pw->pw_uid, pw->pw_gid, 874 pw->pw_gecos, pw->pw_dir, pw->pw_shell)); 1994 NWRAP_LOG(NWRAP_LOG_TRACE, "shell[%s]", pw->pw_shell); 1995 1996 NWRAP_LOG(NWRAP_LOG_DEBUG, 1997 "Added user[%s:%s:%u:%u:%s:%s:%s]", 1998 pw->pw_name, pw->pw_passwd, 1999 pw->pw_uid, pw->pw_gid, 2000 pw->pw_gecos, pw->pw_dir, pw->pw_shell); 875 2001 876 2002 nwrap_pw->num++; … … 883 2009 nwrap_pw = (struct nwrap_pw *)nwrap->private_data; 884 2010 885 if (nwrap_pw->list) free(nwrap_pw->list); 886 887 nwrap_pw->list = NULL; 2011 SAFE_FREE(nwrap_pw->list); 888 2012 nwrap_pw->num = 0; 889 2013 nwrap_pw->idx = 0; … … 904 2028 ofs = PTR_DIFF(last + 1, first); 905 2029 906 if (ofs > buflen) {2030 if (ofs > (off_t) buflen) { 907 2031 return ERANGE; 908 2032 } … … 930 2054 } 931 2055 2056 #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) 2057 static bool nwrap_sp_parse_line(struct nwrap_cache *nwrap, char *line) 2058 { 2059 struct nwrap_sp *nwrap_sp; 2060 struct spwd *sp; 2061 size_t list_size; 2062 char *c; 2063 char *e; 2064 char *p; 2065 2066 nwrap_sp = (struct nwrap_sp *)nwrap->private_data; 2067 2068 list_size = sizeof(*nwrap_sp->list) * (nwrap_sp->num+1); 2069 sp = (struct spwd *)realloc(nwrap_sp->list, list_size); 2070 if (sp == NULL) { 2071 NWRAP_LOG(NWRAP_LOG_ERROR, 2072 "realloc(%u) failed", 2073 (unsigned)list_size); 2074 return false; 2075 } 2076 nwrap_sp->list = sp; 2077 2078 sp = &nwrap_sp->list[nwrap_sp->num]; 2079 2080 c = line; 2081 2082 /* name */ 2083 p = strchr(c, ':'); 2084 if (p == NULL) { 2085 NWRAP_LOG(NWRAP_LOG_ERROR, 2086 "name -- Invalid line[%s]: '%s'", 2087 line, 2088 c); 2089 return false; 2090 } 2091 *p = '\0'; 2092 p++; 2093 sp->sp_namp = c; 2094 c = p; 2095 2096 NWRAP_LOG(NWRAP_LOG_TRACE, "name[%s]\n", sp->sp_namp); 2097 2098 /* pwd */ 2099 p = strchr(c, ':'); 2100 if (p == NULL) { 2101 NWRAP_LOG(NWRAP_LOG_ERROR, 2102 "pwd -- Invalid line[%s]: '%s'", 2103 line, 2104 c); 2105 return false; 2106 } 2107 *p = '\0'; 2108 p++; 2109 sp->sp_pwdp = c; 2110 c = p; 2111 2112 /* lstchg (long) */ 2113 if (c[0] == ':') { 2114 sp->sp_lstchg = -1; 2115 p++; 2116 } else { 2117 p = strchr(c, ':'); 2118 if (p == NULL) { 2119 NWRAP_LOG(NWRAP_LOG_ERROR, 2120 "lstchg -- Invalid line[%s]: '%s'", 2121 line, 2122 c); 2123 return false; 2124 } 2125 *p = '\0'; 2126 p++; 2127 sp->sp_lstchg = strtol(c, &e, 10); 2128 if (c == e) { 2129 NWRAP_LOG(NWRAP_LOG_ERROR, 2130 "lstchg -- Invalid line[%s]: '%s' - %s", 2131 line, c, strerror(errno)); 2132 return false; 2133 } 2134 if (e == NULL) { 2135 NWRAP_LOG(NWRAP_LOG_ERROR, 2136 "lstchg -- Invalid line[%s]: '%s' - %s", 2137 line, c, strerror(errno)); 2138 return false; 2139 } 2140 if (e[0] != '\0') { 2141 NWRAP_LOG(NWRAP_LOG_ERROR, 2142 "lstchg -- Invalid line[%s]: '%s' - %s", 2143 line, c, strerror(errno)); 2144 return false; 2145 } 2146 } 2147 c = p; 2148 2149 /* min (long) */ 2150 if (c[0] == ':') { 2151 sp->sp_min = -1; 2152 p++; 2153 } else { 2154 p = strchr(c, ':'); 2155 if (p == NULL) { 2156 NWRAP_LOG(NWRAP_LOG_ERROR, 2157 "min -- Invalid line[%s]: '%s'", 2158 line, 2159 c); 2160 return false; 2161 } 2162 *p = '\0'; 2163 p++; 2164 sp->sp_min = strtol(c, &e, 10); 2165 if (c == e) { 2166 NWRAP_LOG(NWRAP_LOG_ERROR, 2167 "min -- Invalid line[%s]: '%s' - %s", 2168 line, c, strerror(errno)); 2169 return false; 2170 } 2171 if (e == NULL) { 2172 NWRAP_LOG(NWRAP_LOG_ERROR, 2173 "min -- Invalid line[%s]: '%s' - %s", 2174 line, c, strerror(errno)); 2175 return false; 2176 } 2177 if (e[0] != '\0') { 2178 NWRAP_LOG(NWRAP_LOG_ERROR, 2179 "min -- Invalid line[%s]: '%s' - %s", 2180 line, c, strerror(errno)); 2181 return false; 2182 } 2183 } 2184 c = p; 2185 2186 /* max (long) */ 2187 if (c[0] == ':') { 2188 sp->sp_max = -1; 2189 p++; 2190 } else { 2191 p = strchr(c, ':'); 2192 if (p == NULL) { 2193 NWRAP_LOG(NWRAP_LOG_ERROR, 2194 "max -- Invalid line[%s]: '%s'", 2195 line, 2196 c); 2197 return false; 2198 } 2199 *p = '\0'; 2200 p++; 2201 sp->sp_max = strtol(c, &e, 10); 2202 if (c == e) { 2203 NWRAP_LOG(NWRAP_LOG_ERROR, 2204 "max -- Invalid line[%s]: '%s' - %s", 2205 line, c, strerror(errno)); 2206 return false; 2207 } 2208 if (e == NULL) { 2209 NWRAP_LOG(NWRAP_LOG_ERROR, 2210 "max -- Invalid line[%s]: '%s' - %s", 2211 line, c, strerror(errno)); 2212 return false; 2213 } 2214 if (e[0] != '\0') { 2215 NWRAP_LOG(NWRAP_LOG_ERROR, 2216 "max -- Invalid line[%s]: '%s' - %s", 2217 line, c, strerror(errno)); 2218 return false; 2219 } 2220 } 2221 c = p; 2222 2223 /* warn (long) */ 2224 if (c[0] == ':') { 2225 sp->sp_warn = -1; 2226 p++; 2227 } else { 2228 p = strchr(c, ':'); 2229 if (p == NULL) { 2230 NWRAP_LOG(NWRAP_LOG_ERROR, 2231 "warn -- Invalid line[%s]: '%s'", 2232 line, 2233 c); 2234 return false; 2235 } 2236 *p = '\0'; 2237 p++; 2238 sp->sp_warn = strtol(c, &e, 10); 2239 if (c == e) { 2240 NWRAP_LOG(NWRAP_LOG_ERROR, 2241 "warn -- Invalid line[%s]: '%s' - %s", 2242 line, c, strerror(errno)); 2243 return false; 2244 } 2245 if (e == NULL) { 2246 NWRAP_LOG(NWRAP_LOG_ERROR, 2247 "warn -- Invalid line[%s]: '%s' - %s", 2248 line, c, strerror(errno)); 2249 return false; 2250 } 2251 if (e[0] != '\0') { 2252 NWRAP_LOG(NWRAP_LOG_ERROR, 2253 "warn -- Invalid line[%s]: '%s' - %s", 2254 line, c, strerror(errno)); 2255 return false; 2256 } 2257 } 2258 c = p; 2259 2260 /* inact (long) */ 2261 if (c[0] == ':') { 2262 sp->sp_inact = -1; 2263 p++; 2264 } else { 2265 p = strchr(c, ':'); 2266 if (p == NULL) { 2267 NWRAP_LOG(NWRAP_LOG_ERROR, 2268 "inact -- Invalid line[%s]: '%s'", 2269 line, 2270 c); 2271 return false; 2272 } 2273 *p = '\0'; 2274 p++; 2275 sp->sp_inact = strtol(c, &e, 10); 2276 if (c == e) { 2277 NWRAP_LOG(NWRAP_LOG_ERROR, 2278 "inact -- Invalid line[%s]: '%s' - %s", 2279 line, c, strerror(errno)); 2280 return false; 2281 } 2282 if (e == NULL) { 2283 NWRAP_LOG(NWRAP_LOG_ERROR, 2284 "inact -- Invalid line[%s]: '%s' - %s", 2285 line, c, strerror(errno)); 2286 return false; 2287 } 2288 if (e[0] != '\0') { 2289 NWRAP_LOG(NWRAP_LOG_ERROR, 2290 "inact -- Invalid line[%s]: '%s' - %s", 2291 line, c, strerror(errno)); 2292 return false; 2293 } 2294 } 2295 c = p; 2296 2297 /* expire (long) */ 2298 if (c[0] == ':') { 2299 sp->sp_expire = -1; 2300 p++; 2301 } else { 2302 p = strchr(c, ':'); 2303 if (p == NULL) { 2304 NWRAP_LOG(NWRAP_LOG_ERROR, 2305 "expire -- Invalid line[%s]: '%s'", 2306 line, 2307 c); 2308 return false; 2309 } 2310 *p = '\0'; 2311 p++; 2312 sp->sp_expire = strtol(c, &e, 10); 2313 if (c == e) { 2314 NWRAP_LOG(NWRAP_LOG_ERROR, 2315 "expire -- Invalid line[%s]: '%s' - %s", 2316 line, c, strerror(errno)); 2317 return false; 2318 } 2319 if (e == NULL) { 2320 NWRAP_LOG(NWRAP_LOG_ERROR, 2321 "expire -- Invalid line[%s]: '%s' - %s", 2322 line, c, strerror(errno)); 2323 return false; 2324 } 2325 if (e[0] != '\0') { 2326 NWRAP_LOG(NWRAP_LOG_ERROR, 2327 "expire -- Invalid line[%s]: '%s' - %s", 2328 line, c, strerror(errno)); 2329 return false; 2330 } 2331 } 2332 c = p; 2333 2334 nwrap_sp->num++; 2335 return true; 2336 } 2337 2338 static void nwrap_sp_unload(struct nwrap_cache *nwrap) 2339 { 2340 struct nwrap_sp *nwrap_sp; 2341 nwrap_sp = (struct nwrap_sp *)nwrap->private_data; 2342 2343 SAFE_FREE(nwrap_sp->list); 2344 nwrap_sp->num = 0; 2345 nwrap_sp->idx = 0; 2346 } 2347 #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ 2348 932 2349 /* 933 2350 * the caller has to call nwrap_unload() on failure … … 948 2365 gr = (struct group *)realloc(nwrap_gr->list, list_size); 949 2366 if (!gr) { 950 NWRAP_ ERROR(("%s:realloc failed\n",__location__));2367 NWRAP_LOG(NWRAP_LOG_ERROR, "realloc failed"); 951 2368 return false; 952 2369 } … … 960 2377 p = strchr(c, ':'); 961 2378 if (!p) { 962 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", 963 __location__, line, c)); 2379 NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); 964 2380 return false; 965 2381 } … … 969 2385 c = p; 970 2386 971 NWRAP_ VERBOSE(("name[%s]\n", gr->gr_name));2387 NWRAP_LOG(NWRAP_LOG_TRACE, "name[%s]", gr->gr_name); 972 2388 973 2389 /* password */ 974 2390 p = strchr(c, ':'); 975 2391 if (!p) { 976 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", 977 __location__, line, c)); 2392 NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); 978 2393 return false; 979 2394 } … … 983 2398 c = p; 984 2399 985 NWRAP_ VERBOSE(("password[%s]\n", gr->gr_passwd));2400 NWRAP_LOG(NWRAP_LOG_TRACE, "password[%s]", gr->gr_passwd); 986 2401 987 2402 /* gid */ 988 2403 p = strchr(c, ':'); 989 2404 if (!p) { 990 NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", 991 __location__, line, c)); 2405 NWRAP_LOG(NWRAP_LOG_ERROR, "Invalid line[%s]: '%s'", line, c); 992 2406 return false; 993 2407 } … … 997 2411 gr->gr_gid = (gid_t)strtoul(c, &e, 10); 998 2412 if (c == e) { 999 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", 1000 __location__, line, c, strerror(errno))); 2413 NWRAP_LOG(NWRAP_LOG_ERROR, 2414 "Invalid line[%s]: '%s' - %s", 2415 line, c, strerror(errno)); 1001 2416 return false; 1002 2417 } 1003 2418 if (e == NULL) { 1004 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", 1005 __location__, line, c, strerror(errno))); 2419 NWRAP_LOG(NWRAP_LOG_ERROR, 2420 "Invalid line[%s]: '%s' - %s", 2421 line, c, strerror(errno)); 1006 2422 return false; 1007 2423 } 1008 2424 if (e[0] != '\0') { 1009 NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", 1010 __location__, line, c, strerror(errno))); 2425 NWRAP_LOG(NWRAP_LOG_ERROR, 2426 "Invalid line[%s]: '%s' - %s", 2427 line, c, strerror(errno)); 1011 2428 return false; 1012 2429 } 1013 2430 c = p; 1014 2431 1015 NWRAP_ VERBOSE(("gid[%u]\n", gr->gr_gid));2432 NWRAP_LOG(NWRAP_LOG_TRACE, "gid[%u]", gr->gr_gid); 1016 2433 1017 2434 /* members */ 1018 2435 gr->gr_mem = (char **)malloc(sizeof(char *)); 1019 2436 if (!gr->gr_mem) { 1020 NWRAP_ ERROR(("%s:calloc failed\n",__location__));2437 NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory"); 1021 2438 return false; 1022 2439 } … … 1040 2457 m = (char **)realloc(gr->gr_mem, m_size); 1041 2458 if (!m) { 1042 NWRAP_ERROR(("%s:realloc(%u) failed\n", 1043 __location__, m_size)); 2459 NWRAP_LOG(NWRAP_LOG_ERROR, 2460 "realloc(%zd) failed", 2461 m_size); 1044 2462 return false; 1045 2463 } … … 1048 2466 gr->gr_mem[nummem+1] = NULL; 1049 2467 1050 NWRAP_VERBOSE(("member[%u]: '%s'\n", nummem, gr->gr_mem[nummem])); 1051 } 1052 1053 NWRAP_DEBUG(("add group[%s:%s:%u:] with %u members\n", 1054 gr->gr_name, gr->gr_passwd, gr->gr_gid, nummem)); 2468 NWRAP_LOG(NWRAP_LOG_TRACE, 2469 "member[%u]: '%s'", 2470 nummem, gr->gr_mem[nummem]); 2471 } 2472 2473 NWRAP_LOG(NWRAP_LOG_DEBUG, 2474 "Added group[%s:%s:%u:] with %u members", 2475 gr->gr_name, gr->gr_passwd, gr->gr_gid, nummem); 1055 2476 1056 2477 nwrap_gr->num++; … … 1066 2487 if (nwrap_gr->list) { 1067 2488 for (i=0; i < nwrap_gr->num; i++) { 1068 if (nwrap_gr->list[i].gr_mem) { 1069 free(nwrap_gr->list[i].gr_mem); 1070 } 1071 } 1072 free(nwrap_gr->list); 1073 } 1074 1075 nwrap_gr->list = NULL; 2489 SAFE_FREE(nwrap_gr->list[i].gr_mem); 2490 } 2491 SAFE_FREE(nwrap_gr->list); 2492 } 2493 1076 2494 nwrap_gr->num = 0; 1077 2495 nwrap_gr->idx = 0; … … 1105 2523 ofsm = PTR_DIFF(lastm + 1, src->gr_mem); 1106 2524 1107 if ((ofsb + ofsm) > buflen) {2525 if ((ofsb + ofsm) > (off_t) buflen) { 1108 2526 return ERANGE; 1109 2527 } … … 1131 2549 } 1132 2550 2551 static struct nwrap_entlist *nwrap_entlist_init(struct nwrap_entdata *ed) 2552 { 2553 struct nwrap_entlist *el; 2554 2555 if (ed == NULL) { 2556 NWRAP_LOG(NWRAP_LOG_ERROR, 2557 "entry is NULL, can't create list item"); 2558 return NULL; 2559 } 2560 2561 el = (struct nwrap_entlist *)malloc(sizeof(struct nwrap_entlist)); 2562 if (el == NULL) { 2563 NWRAP_LOG(NWRAP_LOG_ERROR, "malloc failed"); 2564 return NULL; 2565 } 2566 2567 el->next = NULL; 2568 el->ed = ed; 2569 2570 return el; 2571 } 2572 2573 static bool nwrap_ed_inventarize_add_new(char *const h_name, 2574 struct nwrap_entdata *const ed) 2575 { 2576 ENTRY e; 2577 ENTRY *p; 2578 struct nwrap_entlist *el; 2579 bool ok; 2580 2581 if (h_name == NULL) { 2582 NWRAP_LOG(NWRAP_LOG_ERROR, "h_name NULL - can't add"); 2583 return false; 2584 } 2585 2586 el = nwrap_entlist_init(ed); 2587 if (el == NULL) { 2588 return false; 2589 } 2590 2591 e.key = h_name; 2592 e.data = (void *)el; 2593 2594 p = hsearch(e, ENTER); 2595 if (p == NULL) { 2596 NWRAP_LOG(NWRAP_LOG_ERROR, "Hash table is full!"); 2597 return false; 2598 } 2599 2600 ok = nwrap_vector_add_item(&(nwrap_he_global.lists), (void *)el); 2601 if (!ok) { 2602 NWRAP_LOG(NWRAP_LOG_ERROR, 2603 "Failed to add list entry to vector."); 2604 return false; 2605 } 2606 2607 return true; 2608 } 2609 2610 static bool nwrap_ed_inventarize_add_to_existing(struct nwrap_entdata *const ed, 2611 struct nwrap_entlist *const el) 2612 { 2613 struct nwrap_entlist *cursor; 2614 struct nwrap_entlist *el_new; 2615 2616 if (el == NULL) { 2617 NWRAP_LOG(NWRAP_LOG_ERROR, "list is NULL, can not add"); 2618 return false; 2619 } 2620 2621 2622 for (cursor = el; cursor->next != NULL; cursor = cursor->next) 2623 { 2624 if (cursor->ed == ed) { 2625 /* The entry already exists in this list. */ 2626 return true; 2627 } 2628 } 2629 2630 if (cursor->ed == ed) { 2631 /* The entry already exists in this list. */ 2632 return true; 2633 } 2634 2635 el_new = nwrap_entlist_init(ed); 2636 if (el_new == NULL) { 2637 return false; 2638 } 2639 2640 cursor->next = el_new; 2641 return true; 2642 } 2643 2644 static bool nwrap_ed_inventarize(char *const name, 2645 struct nwrap_entdata *const ed) 2646 { 2647 ENTRY e; 2648 ENTRY *p; 2649 bool ok; 2650 2651 e.key = name; 2652 e.data = NULL; 2653 2654 NWRAP_LOG(NWRAP_LOG_DEBUG, "Searching name: %s", e.key); 2655 2656 p = hsearch(e, FIND); 2657 if (p == NULL) { 2658 NWRAP_LOG(NWRAP_LOG_DEBUG, "Name %s not found. Adding...", name); 2659 ok = nwrap_ed_inventarize_add_new(name, ed); 2660 } else { 2661 struct nwrap_entlist *el = (struct nwrap_entlist *)p->data; 2662 2663 NWRAP_LOG(NWRAP_LOG_DEBUG, "Name %s found. Add record to list.", name); 2664 ok = nwrap_ed_inventarize_add_to_existing(ed, el); 2665 } 2666 2667 return ok; 2668 } 2669 2670 static bool nwrap_add_hname(struct nwrap_entdata *const ed) 2671 { 2672 char *const h_name = (char *const)(ed->ht.h_name); 2673 unsigned i; 2674 bool ok; 2675 2676 ok = nwrap_ed_inventarize(h_name, ed); 2677 if (!ok) { 2678 return false; 2679 } 2680 2681 if (ed->ht.h_aliases == NULL) { 2682 return true; 2683 } 2684 2685 /* Itemize aliases */ 2686 for (i = 0; ed->ht.h_aliases[i] != NULL; ++i) { 2687 char *h_name_alias; 2688 2689 h_name_alias = ed->ht.h_aliases[i]; 2690 2691 NWRAP_LOG(NWRAP_LOG_DEBUG, "Add alias: %s", h_name_alias); 2692 2693 if (!nwrap_ed_inventarize(h_name_alias, ed)) { 2694 NWRAP_LOG(NWRAP_LOG_ERROR, 2695 "Unable to add alias: %s", h_name_alias); 2696 return false; 2697 } 2698 } 2699 2700 return true; 2701 } 2702 2703 static bool nwrap_he_parse_line(struct nwrap_cache *nwrap, char *line) 2704 { 2705 struct nwrap_he *nwrap_he = (struct nwrap_he *)nwrap->private_data; 2706 bool do_aliases = true; 2707 ssize_t aliases_count = 0; 2708 char *p; 2709 char *i; 2710 char *n; 2711 2712 char *ip; 2713 bool ok; 2714 2715 struct nwrap_entdata *ed = (struct nwrap_entdata *) 2716 malloc(sizeof(struct nwrap_entdata)); 2717 if (ed == NULL) { 2718 NWRAP_LOG(NWRAP_LOG_ERROR, 2719 "Unable to allocate memory for nwrap_entdata"); 2720 return false; 2721 } 2722 ZERO_STRUCTP(ed); 2723 2724 i = line; 2725 2726 /* 2727 * IP 2728 */ 2729 2730 /* Walk to first char */ 2731 for (p = i; *p != '.' && *p != ':' && !isxdigit((int) *p); p++) { 2732 if (*p == '\0') { 2733 NWRAP_LOG(NWRAP_LOG_ERROR, 2734 "Invalid line[%s]: '%s'", 2735 line, i); 2736 free(ed); 2737 return false; 2738 } 2739 } 2740 2741 for (i = p; !isspace((int)*p); p++) { 2742 if (*p == '\0') { 2743 NWRAP_LOG(NWRAP_LOG_ERROR, 2744 "Invalid line[%s]: '%s'", 2745 line, i); 2746 free(ed); 2747 return false; 2748 } 2749 } 2750 2751 *p = '\0'; 2752 2753 if (inet_pton(AF_INET, i, ed->addr.host_addr)) { 2754 ed->ht.h_addrtype = AF_INET; 2755 ed->ht.h_length = 4; 2756 #ifdef HAVE_IPV6 2757 } else if (inet_pton(AF_INET6, i, ed->addr.host_addr)) { 2758 ed->ht.h_addrtype = AF_INET6; 2759 ed->ht.h_length = 16; 2760 #endif 2761 } else { 2762 NWRAP_LOG(NWRAP_LOG_ERROR, 2763 "Invalid line[%s]: '%s'", 2764 line, i); 2765 2766 free(ed); 2767 return false; 2768 } 2769 ip = i; 2770 2771 ok = nwrap_vector_add_item(&(ed->nwrap_addrdata), 2772 (void *const)ed->addr.host_addr); 2773 if (!ok) { 2774 NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to add addrdata to vector"); 2775 free(ed); 2776 return false; 2777 } 2778 ed->ht.h_addr_list = nwrap_vector_head(&ed->nwrap_addrdata); 2779 2780 p++; 2781 2782 /* 2783 * FQDN 2784 */ 2785 2786 /* Walk to first char */ 2787 for (n = p; *p != '_' && !isalnum((int) *p); p++) { 2788 if (*p == '\0') { 2789 NWRAP_LOG(NWRAP_LOG_ERROR, 2790 "Invalid line[%s]: '%s'", 2791 line, n); 2792 2793 free(ed); 2794 return false; 2795 } 2796 } 2797 2798 for (n = p; !isspace((int)*p); p++) { 2799 if (*p == '\0') { 2800 do_aliases = false; 2801 break; 2802 } 2803 } 2804 2805 *p = '\0'; 2806 2807 /* Convert to lowercase. This operate on same memory region */ 2808 str_tolower(n, n); 2809 ed->ht.h_name = n; 2810 2811 /* glib's getent always dereferences he->h_aliases */ 2812 ed->ht.h_aliases = malloc(sizeof(char *)); 2813 if (ed->ht.h_aliases == NULL) { 2814 free(ed); 2815 return false; 2816 } 2817 ed->ht.h_aliases[0] = NULL; 2818 2819 /* 2820 * Aliases 2821 */ 2822 while (do_aliases) { 2823 char **aliases; 2824 char *a; 2825 2826 p++; 2827 2828 /* Walk to first char */ 2829 for (a = p; *p != '_' && !isalnum((int) *p); p++) { 2830 if (*p == '\0') { 2831 do_aliases = false; 2832 break; 2833 } 2834 } 2835 /* Only trailing spaces are left */ 2836 if (!do_aliases) { 2837 break; 2838 } 2839 2840 for (a = p; !isspace((int)*p); p++) { 2841 if (*p == '\0') { 2842 do_aliases = false; 2843 break; 2844 } 2845 } 2846 2847 *p = '\0'; 2848 2849 aliases = realloc(ed->ht.h_aliases, sizeof(char *) * (aliases_count + 2)); 2850 if (aliases == NULL) { 2851 free(ed); 2852 return false; 2853 } 2854 ed->ht.h_aliases = aliases; 2855 2856 str_tolower(a, a); 2857 aliases[aliases_count] = a; 2858 aliases[aliases_count + 1] = NULL; 2859 2860 aliases_count += 1; 2861 } 2862 2863 ok = nwrap_vector_add_item(&(nwrap_he->entries), (void *const)ed); 2864 if (!ok) { 2865 NWRAP_LOG(NWRAP_LOG_ERROR, "Unable to add entry to vector"); 2866 free(ed); 2867 return false; 2868 } 2869 2870 ed->aliases_count = aliases_count; 2871 /* Inventarize item */ 2872 ok = nwrap_add_hname(ed); 2873 if (!ok) { 2874 return false; 2875 } 2876 2877 ok = nwrap_ed_inventarize(ip, ed); 2878 if (!ok) { 2879 return false; 2880 } 2881 2882 nwrap_he->num++; 2883 return true; 2884 } 2885 2886 static void nwrap_he_unload(struct nwrap_cache *nwrap) 2887 { 2888 struct nwrap_he *nwrap_he = 2889 (struct nwrap_he *)nwrap->private_data; 2890 struct nwrap_entdata *ed; 2891 struct nwrap_entlist *el; 2892 size_t i; 2893 int rc; 2894 2895 nwrap_vector_foreach (ed, nwrap_he->entries, i) 2896 { 2897 SAFE_FREE(ed->nwrap_addrdata.items); 2898 SAFE_FREE(ed->ht.h_aliases); 2899 SAFE_FREE(ed); 2900 } 2901 SAFE_FREE(nwrap_he->entries.items); 2902 nwrap_he->entries.count = nwrap_he->entries.capacity = 0; 2903 2904 nwrap_vector_foreach(el, nwrap_he->lists, i) 2905 { 2906 while (el != NULL) { 2907 struct nwrap_entlist *el_next; 2908 2909 el_next = el->next; 2910 SAFE_FREE(el); 2911 el = el_next; 2912 } 2913 } 2914 SAFE_FREE(nwrap_he->lists.items); 2915 nwrap_he->lists.count = nwrap_he->lists.capacity = 0; 2916 2917 nwrap_he->num = 0; 2918 nwrap_he->idx = 0; 2919 2920 /* 2921 * If we unload the file, the pointers in the hash table point to 2922 * invalid memory. So we need to destroy the hash table and recreate 2923 * it. 2924 */ 2925 hdestroy(); 2926 rc = hcreate(max_hostents); 2927 if (rc == 0) { 2928 NWRAP_LOG(NWRAP_LOG_ERROR, "Failed to initialize hash table"); 2929 exit(-1); 2930 } 2931 } 2932 2933 1133 2934 /* user functions */ 1134 2935 static struct passwd *nwrap_files_getpwnam(struct nwrap_backend *b, … … 1136 2937 { 1137 2938 int i; 1138 1139 nwrap_files_cache_reload(nwrap_pw_global.cache); 2939 bool ok; 2940 2941 (void) b; /* unused */ 2942 2943 NWRAP_LOG(NWRAP_LOG_DEBUG, "Lookup user %s in files", name); 2944 2945 ok = nwrap_files_cache_reload(nwrap_pw_global.cache); 2946 if (!ok) { 2947 NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading passwd file"); 2948 return NULL; 2949 } 1140 2950 1141 2951 for (i=0; i<nwrap_pw_global.num; i++) { 1142 2952 if (strcmp(nwrap_pw_global.list[i].pw_name, name) == 0) { 1143 NWRAP_DEBUG(("%s: user[%s] found\n", 1144 __location__, name)); 2953 NWRAP_LOG(NWRAP_LOG_DEBUG, "user[%s] found", name); 1145 2954 return &nwrap_pw_global.list[i]; 1146 2955 } 1147 NWRAP_VERBOSE(("%s: user[%s] does not match [%s]\n", 1148 __location__, name, 1149 nwrap_pw_global.list[i].pw_name)); 1150 } 1151 1152 NWRAP_DEBUG(("%s: user[%s] not found\n", __location__, name)); 2956 NWRAP_LOG(NWRAP_LOG_DEBUG, 2957 "user[%s] does not match [%s]", 2958 name, 2959 nwrap_pw_global.list[i].pw_name); 2960 } 2961 2962 NWRAP_LOG(NWRAP_LOG_DEBUG, "user[%s] not found\n", name); 1153 2963 1154 2964 errno = ENOENT; … … 1177 2987 { 1178 2988 int i; 1179 1180 nwrap_files_cache_reload(nwrap_pw_global.cache); 2989 bool ok; 2990 2991 (void) b; /* unused */ 2992 2993 ok = nwrap_files_cache_reload(nwrap_pw_global.cache); 2994 if (!ok) { 2995 NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading passwd file"); 2996 return NULL; 2997 } 1181 2998 1182 2999 for (i=0; i<nwrap_pw_global.num; i++) { 1183 3000 if (nwrap_pw_global.list[i].pw_uid == uid) { 1184 NWRAP_DEBUG(("%s: uid[%u] found\n", 1185 __location__, uid)); 3001 NWRAP_LOG(NWRAP_LOG_DEBUG, "uid[%u] found", uid); 1186 3002 return &nwrap_pw_global.list[i]; 1187 3003 } 1188 NWRAP_VERBOSE(("%s: uid[%u] does not match [%u]\n", 1189 __location__, uid, 1190 nwrap_pw_global.list[i].pw_uid)); 1191 } 1192 1193 NWRAP_DEBUG(("%s: uid[%u] not found\n", __location__, uid)); 3004 NWRAP_LOG(NWRAP_LOG_DEBUG, 3005 "uid[%u] does not match [%u]", 3006 uid, 3007 nwrap_pw_global.list[i].pw_uid); 3008 } 3009 3010 NWRAP_LOG(NWRAP_LOG_DEBUG, "uid[%u] not found\n", uid); 1194 3011 1195 3012 errno = ENOENT; … … 1217 3034 static void nwrap_files_setpwent(struct nwrap_backend *b) 1218 3035 { 3036 (void) b; /* unused */ 3037 1219 3038 nwrap_pw_global.idx = 0; 1220 3039 } … … 1224 3043 struct passwd *pw; 1225 3044 3045 (void) b; /* unused */ 3046 1226 3047 if (nwrap_pw_global.idx == 0) { 1227 nwrap_files_cache_reload(nwrap_pw_global.cache); 3048 bool ok; 3049 ok = nwrap_files_cache_reload(nwrap_pw_global.cache); 3050 if (!ok) { 3051 NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading passwd file"); 3052 return NULL; 3053 } 1228 3054 } 1229 3055 … … 1235 3061 pw = &nwrap_pw_global.list[nwrap_pw_global.idx++]; 1236 3062 1237 NWRAP_VERBOSE(("%s: return user[%s] uid[%u]\n", 1238 __location__, pw->pw_name, pw->pw_uid)); 3063 NWRAP_LOG(NWRAP_LOG_DEBUG, 3064 "return user[%s] uid[%u]", 3065 pw->pw_name, pw->pw_uid); 1239 3066 1240 3067 return pw; … … 1260 3087 static void nwrap_files_endpwent(struct nwrap_backend *b) 1261 3088 { 3089 (void) b; /* unused */ 3090 1262 3091 nwrap_pw_global.idx = 0; 1263 3092 } 3093 3094 /* shadow */ 3095 3096 #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) 3097 3098 #ifdef HAVE_SETSPENT 3099 static void nwrap_files_setspent(void) 3100 { 3101 nwrap_sp_global.idx = 0; 3102 } 3103 3104 static struct spwd *nwrap_files_getspent(void) 3105 { 3106 struct spwd *sp; 3107 3108 if (nwrap_sp_global.idx == 0) { 3109 bool ok; 3110 3111 ok = nwrap_files_cache_reload(nwrap_sp_global.cache); 3112 if (!ok) { 3113 NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading shadow file"); 3114 return NULL; 3115 } 3116 } 3117 3118 if (nwrap_sp_global.idx >= nwrap_sp_global.num) { 3119 errno = ENOENT; 3120 return NULL; 3121 } 3122 3123 sp = &nwrap_sp_global.list[nwrap_sp_global.idx++]; 3124 3125 NWRAP_LOG(NWRAP_LOG_DEBUG, 3126 "return user[%s]", 3127 sp->sp_namp); 3128 3129 return sp; 3130 } 3131 3132 static void nwrap_files_endspent(void) 3133 { 3134 nwrap_sp_global.idx = 0; 3135 } 3136 #endif /* HAVE_SETSPENT */ 3137 3138 static struct spwd *nwrap_files_getspnam(const char *name) 3139 { 3140 int i; 3141 bool ok; 3142 3143 NWRAP_LOG(NWRAP_LOG_DEBUG, "Lookup user %s in files", name); 3144 3145 ok = nwrap_files_cache_reload(nwrap_sp_global.cache); 3146 if (!ok) { 3147 NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading shadow file"); 3148 return NULL; 3149 } 3150 3151 for (i=0; i<nwrap_sp_global.num; i++) { 3152 if (strcmp(nwrap_sp_global.list[i].sp_namp, name) == 0) { 3153 NWRAP_LOG(NWRAP_LOG_DEBUG, "user[%s] found", name); 3154 return &nwrap_sp_global.list[i]; 3155 } 3156 NWRAP_LOG(NWRAP_LOG_DEBUG, 3157 "user[%s] does not match [%s]", 3158 name, 3159 nwrap_sp_global.list[i].sp_namp); 3160 } 3161 3162 NWRAP_LOG(NWRAP_LOG_DEBUG, "user[%s] not found\n", name); 3163 3164 errno = ENOENT; 3165 return NULL; 3166 } 3167 #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ 1264 3168 1265 3169 /* misc functions */ 1266 3170 static int nwrap_files_initgroups(struct nwrap_backend *b, 1267 const char *user, gid_t group) 1268 { 1269 /* TODO: maybe we should also fake this... */ 1270 return EPERM; 3171 const char *user, 3172 gid_t group) 3173 { 3174 struct group *grp; 3175 gid_t *groups; 3176 int size = 1; 3177 int rc; 3178 3179 groups = (gid_t *)malloc(size * sizeof(gid_t)); 3180 if (groups == NULL) { 3181 NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory"); 3182 errno = ENOMEM; 3183 return -1; 3184 } 3185 groups[0] = group; 3186 3187 nwrap_files_setgrent(b); 3188 while ((grp = nwrap_files_getgrent(b)) != NULL) { 3189 int i = 0; 3190 3191 NWRAP_LOG(NWRAP_LOG_DEBUG, 3192 "Inspecting %s for group membership", 3193 grp->gr_name); 3194 3195 for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) { 3196 if (group != grp->gr_gid && 3197 (strcmp(user, grp->gr_mem[i]) == 0)) { 3198 NWRAP_LOG(NWRAP_LOG_DEBUG, 3199 "%s is member of %s", 3200 user, 3201 grp->gr_name); 3202 3203 groups = (gid_t *)realloc(groups, 3204 (size + 1) * sizeof(gid_t)); 3205 if (groups == NULL) { 3206 NWRAP_LOG(NWRAP_LOG_ERROR, 3207 "Out of memory"); 3208 errno = ENOMEM; 3209 return -1; 3210 } 3211 3212 groups[size] = grp->gr_gid; 3213 size++; 3214 } 3215 } 3216 } 3217 3218 nwrap_files_endgrent(b); 3219 3220 NWRAP_LOG(NWRAP_LOG_DEBUG, 3221 "%s is member of %d groups", 3222 user, size); 3223 3224 /* This really only works if uid_wrapper is loaded */ 3225 rc = setgroups(size, groups); 3226 3227 free(groups); 3228 3229 return rc; 1271 3230 } 1272 3231 … … 1276 3235 { 1277 3236 int i; 1278 1279 nwrap_files_cache_reload(nwrap_gr_global.cache); 3237 bool ok; 3238 3239 (void) b; /* unused */ 3240 3241 ok = nwrap_files_cache_reload(nwrap_gr_global.cache); 3242 if (!ok) { 3243 NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading group file"); 3244 return NULL; 3245 } 1280 3246 1281 3247 for (i=0; i<nwrap_gr_global.num; i++) { 1282 3248 if (strcmp(nwrap_gr_global.list[i].gr_name, name) == 0) { 1283 NWRAP_DEBUG(("%s: group[%s] found\n", 1284 __location__, name)); 3249 NWRAP_LOG(NWRAP_LOG_DEBUG, "group[%s] found", name); 1285 3250 return &nwrap_gr_global.list[i]; 1286 3251 } 1287 NWRAP_VERBOSE(("%s: group[%s] does not match [%s]\n", 1288 __location__, name, 1289 nwrap_gr_global.list[i].gr_name)); 1290 } 1291 1292 NWRAP_DEBUG(("%s: group[%s] not found\n", __location__, name)); 3252 NWRAP_LOG(NWRAP_LOG_DEBUG, 3253 "group[%s] does not match [%s]", 3254 name, 3255 nwrap_gr_global.list[i].gr_name); 3256 } 3257 3258 NWRAP_LOG(NWRAP_LOG_DEBUG, "group[%s] not found", name); 1293 3259 1294 3260 errno = ENOENT; … … 1317 3283 { 1318 3284 int i; 1319 1320 nwrap_files_cache_reload(nwrap_gr_global.cache); 3285 bool ok; 3286 3287 (void) b; /* unused */ 3288 3289 ok = nwrap_files_cache_reload(nwrap_gr_global.cache); 3290 if (!ok) { 3291 NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading group file"); 3292 return NULL; 3293 } 1321 3294 1322 3295 for (i=0; i<nwrap_gr_global.num; i++) { 1323 3296 if (nwrap_gr_global.list[i].gr_gid == gid) { 1324 NWRAP_DEBUG(("%s: gid[%u] found\n", 1325 __location__, gid)); 3297 NWRAP_LOG(NWRAP_LOG_DEBUG, "gid[%u] found", gid); 1326 3298 return &nwrap_gr_global.list[i]; 1327 3299 } 1328 NWRAP_VERBOSE(("%s: gid[%u] does not match [%u]\n", 1329 __location__, gid, 1330 nwrap_gr_global.list[i].gr_gid)); 1331 } 1332 1333 NWRAP_DEBUG(("%s: gid[%u] not found\n", __location__, gid)); 3300 NWRAP_LOG(NWRAP_LOG_DEBUG, 3301 "gid[%u] does not match [%u]", 3302 gid, 3303 nwrap_gr_global.list[i].gr_gid); 3304 } 3305 3306 NWRAP_LOG(NWRAP_LOG_DEBUG, "gid[%u] not found", gid); 1334 3307 1335 3308 errno = ENOENT; … … 1357 3330 static void nwrap_files_setgrent(struct nwrap_backend *b) 1358 3331 { 3332 (void) b; /* unused */ 3333 1359 3334 nwrap_gr_global.idx = 0; 1360 3335 } … … 1364 3339 struct group *gr; 1365 3340 3341 (void) b; /* unused */ 3342 1366 3343 if (nwrap_gr_global.idx == 0) { 1367 nwrap_files_cache_reload(nwrap_gr_global.cache); 3344 bool ok; 3345 3346 ok = nwrap_files_cache_reload(nwrap_gr_global.cache); 3347 if (!ok) { 3348 NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading group file"); 3349 return NULL; 3350 } 1368 3351 } 1369 3352 … … 1375 3358 gr = &nwrap_gr_global.list[nwrap_gr_global.idx++]; 1376 3359 1377 NWRAP_VERBOSE(("%s: return group[%s] gid[%u]\n", 1378 __location__, gr->gr_name, gr->gr_gid)); 3360 NWRAP_LOG(NWRAP_LOG_DEBUG, 3361 "return group[%s] gid[%u]", 3362 gr->gr_name, gr->gr_gid); 1379 3363 1380 3364 return gr; … … 1400 3384 static void nwrap_files_endgrent(struct nwrap_backend *b) 1401 3385 { 3386 (void) b; /* unused */ 3387 1402 3388 nwrap_gr_global.idx = 0; 3389 } 3390 3391 /* hosts functions */ 3392 static int nwrap_files_gethostbyname(const char *name, int af, 3393 struct hostent *result, 3394 struct nwrap_vector *addr_list) 3395 { 3396 struct nwrap_entlist *el; 3397 struct hostent *he; 3398 char *h_name_lower; 3399 ENTRY e; 3400 ENTRY *e_p; 3401 char canon_name[DNS_NAME_MAX] = { 0 }; 3402 size_t name_len; 3403 bool he_found = false; 3404 bool ok; 3405 3406 ok = nwrap_files_cache_reload(nwrap_he_global.cache); 3407 if (!ok) { 3408 NWRAP_LOG(NWRAP_LOG_ERROR, "error loading hosts file"); 3409 goto no_ent; 3410 } 3411 3412 name_len = strlen(name); 3413 if (name_len < sizeof(canon_name) && name[name_len - 1] == '.') { 3414 strncpy(canon_name, name, name_len - 1); 3415 name = canon_name; 3416 } 3417 3418 if (!str_tolower_copy(&h_name_lower, name)) { 3419 NWRAP_LOG(NWRAP_LOG_DEBUG, 3420 "Out of memory while converting to lower case"); 3421 goto no_ent; 3422 } 3423 3424 /* Look at hash table for element */ 3425 NWRAP_LOG(NWRAP_LOG_DEBUG, "Searching for name: %s", h_name_lower); 3426 e.key = h_name_lower; 3427 e.data = NULL; 3428 e_p = hsearch(e, FIND); 3429 if (e_p == NULL) { 3430 NWRAP_LOG(NWRAP_LOG_DEBUG, "Name %s not found.", h_name_lower); 3431 SAFE_FREE(h_name_lower); 3432 goto no_ent; 3433 } 3434 SAFE_FREE(h_name_lower); 3435 3436 /* Always cleanup vector and results */ 3437 if (!nwrap_vector_is_initialized(addr_list)) { 3438 if (!nwrap_vector_init(addr_list)) { 3439 NWRAP_LOG(NWRAP_LOG_DEBUG, 3440 "Unable to initialize memory for addr_list vector"); 3441 goto no_ent; 3442 } 3443 } else { 3444 /* When vector is initialized data are valid no more. 3445 * Quick way how to free vector is: */ 3446 addr_list->count = 0; 3447 } 3448 3449 /* Iterate through results */ 3450 for (el = (struct nwrap_entlist *)e_p->data; el != NULL; el = el->next) 3451 { 3452 he = &(el->ed->ht); 3453 3454 /* Filter by address familiy if provided */ 3455 if (af != AF_UNSPEC && he->h_addrtype != af) { 3456 continue; 3457 } 3458 3459 /* 3460 * GLIBC HACK? 3461 * glibc doesn't return ipv6 addresses when AF_UNSPEC is used 3462 */ 3463 if (af == AF_UNSPEC && he->h_addrtype != AF_INET) { 3464 continue; 3465 } 3466 3467 if (!he_found) { 3468 memcpy(result, he, sizeof(struct hostent)); 3469 NWRAP_LOG(NWRAP_LOG_DEBUG, 3470 "Name found. Returning record for %s", 3471 he->h_name); 3472 he_found = true; 3473 } 3474 nwrap_vector_merge(addr_list, &el->ed->nwrap_addrdata); 3475 result->h_addr_list = nwrap_vector_head(addr_list); 3476 } 3477 3478 if (he_found) { 3479 return 0; 3480 } 3481 NWRAP_LOG(NWRAP_LOG_DEBUG, 3482 "Name found in database. No records matches type."); 3483 3484 no_ent: 3485 errno = ENOENT; 3486 return -1; 3487 } 3488 3489 #ifdef HAVE_GETHOSTBYNAME_R 3490 static int nwrap_gethostbyname_r(const char *name, 3491 struct hostent *ret, 3492 char *buf, size_t buflen, 3493 struct hostent **result, int *h_errnop) 3494 { 3495 struct nwrap_vector *addr_list = malloc(sizeof(struct nwrap_vector)); 3496 int rc; 3497 3498 if (addr_list == NULL) { 3499 NWRAP_LOG(NWRAP_LOG_ERROR, 3500 "Unable to allocate memory for address list"); 3501 errno = ENOENT; 3502 return -1; 3503 } 3504 3505 ZERO_STRUCTP(addr_list); 3506 3507 rc = nwrap_files_gethostbyname(name, AF_UNSPEC, ret, addr_list); 3508 if (rc == -1) { 3509 *h_errnop = h_errno; 3510 if (addr_list->items != NULL) { 3511 free(addr_list->items); 3512 } 3513 SAFE_FREE(addr_list); 3514 errno = ENOENT; 3515 return -1; 3516 } 3517 3518 if (buflen < (addr_list->count * sizeof(void *))) { 3519 SAFE_FREE(addr_list->items); 3520 SAFE_FREE(addr_list); 3521 return ERANGE; 3522 } 3523 3524 /* Copy all to user provided buffer and change 3525 * pointers in returned structure. 3526 * +1 is for ending NULL pointer. */ 3527 memcpy(buf, addr_list->items, (addr_list->count + 1) * sizeof(void *)); 3528 3529 free(addr_list->items); 3530 free(addr_list); 3531 3532 ret->h_addr_list = (char **)buf; 3533 *result = ret; 3534 return 0; 3535 } 3536 3537 int gethostbyname_r(const char *name, 3538 struct hostent *ret, 3539 char *buf, size_t buflen, 3540 struct hostent **result, int *h_errnop) 3541 { 3542 if (!nss_wrapper_hosts_enabled()) { 3543 return libc_gethostbyname_r(name, 3544 ret, 3545 buf, 3546 buflen, 3547 result, 3548 h_errnop); 3549 } 3550 3551 return nwrap_gethostbyname_r(name, ret, buf, buflen, result, h_errnop); 3552 } 3553 #endif 3554 3555 static int nwrap_files_getaddrinfo(const char *name, 3556 unsigned short port, 3557 const struct addrinfo *hints, 3558 struct addrinfo **ai) 3559 { 3560 struct nwrap_entlist *el; 3561 struct hostent *he; 3562 struct addrinfo *ai_head = NULL; 3563 struct addrinfo *ai_cur = NULL; 3564 char *h_name_lower; 3565 size_t name_len; 3566 char canon_name[DNS_NAME_MAX] = { 0 }; 3567 bool skip_canonname = false; 3568 ENTRY e = { 3569 .key = NULL, 3570 }; 3571 ENTRY *e_p = NULL; 3572 int rc; 3573 bool ok; 3574 3575 ok = nwrap_files_cache_reload(nwrap_he_global.cache); 3576 if (!ok) { 3577 NWRAP_LOG(NWRAP_LOG_ERROR, "error loading hosts file"); 3578 return EAI_SYSTEM; 3579 } 3580 3581 name_len = strlen(name); 3582 if (name_len < DNS_NAME_MAX && name[name_len - 1] == '.') { 3583 strncpy(canon_name, name, name_len - 1); 3584 name = canon_name; 3585 } 3586 3587 if (!str_tolower_copy(&h_name_lower, name)) { 3588 NWRAP_LOG(NWRAP_LOG_DEBUG, 3589 "Out of memory while converting to lower case"); 3590 return EAI_MEMORY; 3591 } 3592 3593 NWRAP_LOG(NWRAP_LOG_DEBUG, "Searching for name: %s", h_name_lower); 3594 e.key = h_name_lower; 3595 e.data = NULL; 3596 e_p = hsearch(e, FIND); 3597 if (e_p == NULL) { 3598 NWRAP_LOG(NWRAP_LOG_DEBUG, "Name %s not found.", h_name_lower); 3599 SAFE_FREE(h_name_lower); 3600 errno = ENOENT; 3601 return EAI_NONAME; 3602 } 3603 NWRAP_LOG(NWRAP_LOG_DEBUG, "Name: %s found.", h_name_lower); 3604 SAFE_FREE(h_name_lower); 3605 3606 rc = EAI_NONAME; 3607 for (el = (struct nwrap_entlist *)e_p->data; el != NULL; el = el->next) 3608 { 3609 int rc2; 3610 struct addrinfo *ai_new = NULL; 3611 3612 he = &(el->ed->ht); 3613 3614 if (hints->ai_family != AF_UNSPEC && 3615 he->h_addrtype != hints->ai_family) 3616 { 3617 NWRAP_LOG(NWRAP_LOG_DEBUG, 3618 "Entry found but with wrong AF - " 3619 "remembering EAI_ADDRINFO."); 3620 rc = EAI_ADDRFAMILY; 3621 continue; 3622 } 3623 3624 /* Function allocates memory and returns it in ai. */ 3625 rc2 = nwrap_convert_he_ai(he, 3626 port, 3627 hints, 3628 &ai_new, 3629 skip_canonname); 3630 if (rc2 != 0) { 3631 NWRAP_LOG(NWRAP_LOG_ERROR, "Error converting he to ai"); 3632 if (ai_head != NULL) { 3633 freeaddrinfo(ai_head); 3634 } 3635 return rc2; 3636 } 3637 skip_canonname = true; 3638 3639 if (ai_head == NULL) { 3640 ai_head = ai_new; 3641 } 3642 if (ai_cur != NULL) { 3643 ai_cur->ai_next = ai_new; 3644 } 3645 ai_cur = ai_new; 3646 } 3647 3648 if (ai_head != NULL) { 3649 rc = 0; 3650 } 3651 3652 *ai = ai_head; 3653 3654 return rc; 3655 } 3656 3657 static struct hostent *nwrap_files_gethostbyaddr(const void *addr, 3658 socklen_t len, int type) 3659 { 3660 struct hostent *he; 3661 char ip[NWRAP_INET_ADDRSTRLEN] = {0}; 3662 struct nwrap_entdata *ed; 3663 const char *a; 3664 size_t i; 3665 bool ok; 3666 3667 (void) len; /* unused */ 3668 3669 ok = nwrap_files_cache_reload(nwrap_he_global.cache); 3670 if (!ok) { 3671 NWRAP_LOG(NWRAP_LOG_ERROR, "error loading hosts file"); 3672 return NULL; 3673 } 3674 3675 a = inet_ntop(type, addr, ip, sizeof(ip)); 3676 if (a == NULL) { 3677 errno = EINVAL; 3678 return NULL; 3679 } 3680 3681 nwrap_vector_foreach(ed, nwrap_he_global.entries, i) 3682 { 3683 he = &(ed->ht); 3684 if (he->h_addrtype != type) { 3685 continue; 3686 } 3687 3688 if (memcmp(addr, he->h_addr_list[0], he->h_length) == 0) { 3689 return he; 3690 } 3691 } 3692 3693 errno = ENOENT; 3694 return NULL; 3695 } 3696 3697 #ifdef HAVE_GETHOSTBYADDR_R 3698 static int nwrap_gethostbyaddr_r(const void *addr, socklen_t len, int type, 3699 struct hostent *ret, 3700 char *buf, size_t buflen, 3701 struct hostent **result, int *h_errnop) 3702 { 3703 *result = nwrap_files_gethostbyaddr(addr, len, type); 3704 if (*result != NULL) { 3705 memset(buf, '\0', buflen); 3706 *ret = **result; 3707 return 0; 3708 } else { 3709 *h_errnop = h_errno; 3710 return -1; 3711 } 3712 } 3713 3714 int gethostbyaddr_r(const void *addr, socklen_t len, int type, 3715 struct hostent *ret, 3716 char *buf, size_t buflen, 3717 struct hostent **result, int *h_errnop) 3718 { 3719 if (!nss_wrapper_hosts_enabled()) { 3720 return libc_gethostbyaddr_r(addr, 3721 len, 3722 type, 3723 ret, 3724 buf, 3725 buflen, 3726 result, 3727 h_errnop); 3728 } 3729 3730 return nwrap_gethostbyaddr_r(addr, len, type, ret, buf, buflen, result, h_errnop); 3731 } 3732 #endif 3733 3734 /* hosts enum functions */ 3735 static void nwrap_files_sethostent(void) 3736 { 3737 nwrap_he_global.idx = 0; 3738 } 3739 3740 static struct hostent *nwrap_files_gethostent(void) 3741 { 3742 struct hostent *he; 3743 3744 if (nwrap_he_global.idx == 0) { 3745 bool ok; 3746 3747 ok = nwrap_files_cache_reload(nwrap_he_global.cache); 3748 if (!ok) { 3749 NWRAP_LOG(NWRAP_LOG_ERROR, "Error loading hosts file"); 3750 return NULL; 3751 } 3752 } 3753 3754 if (nwrap_he_global.idx >= nwrap_he_global.num) { 3755 errno = ENOENT; 3756 return NULL; 3757 } 3758 3759 he = &((struct nwrap_entdata *)nwrap_he_global.entries.items[nwrap_he_global.idx++])->ht; 3760 3761 NWRAP_LOG(NWRAP_LOG_DEBUG, "return hosts[%s]", he->h_name); 3762 3763 return he; 3764 } 3765 3766 static void nwrap_files_endhostent(void) 3767 { 3768 nwrap_he_global.idx = 0; 1403 3769 } 1404 3770 … … 1407 3773 */ 1408 3774 1409 #ifndef SAFE_FREE1410 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)1411 #endif1412 3775 1413 3776 static struct passwd *nwrap_module_getpwnam(struct nwrap_backend *b, … … 1429 3792 return NULL; 1430 3793 } 3794 1431 3795 return &pwd; 1432 3796 } … … 1437 3801 { 1438 3802 int ret; 3803 3804 (void) b; /* unused */ 3805 (void) pwdst; /* unused */ 3806 (void) pwdstp; /* unused */ 1439 3807 1440 3808 if (!b->fns->_nss_getpwnam_r) { … … 1491 3859 int ret; 1492 3860 3861 (void) pwdstp; /* unused */ 3862 1493 3863 if (!b->fns->_nss_getpwuid_r) { 1494 3864 return ENOENT; … … 1552 3922 int ret; 1553 3923 3924 (void) pwdstp; /* unused */ 3925 1554 3926 if (!b->fns->_nss_getpwent_r) { 1555 3927 return ENOENT; … … 1643 4015 int ret; 1644 4016 4017 (void) grdstp; /* unused */ 4018 1645 4019 if (!b->fns->_nss_getgrnam_r) { 1646 4020 return ENOENT; … … 1712 4086 int ret; 1713 4087 4088 (void) grdstp; /* unused */ 4089 1714 4090 if (!b->fns->_nss_getgrgid_r) { 1715 4091 return ENOENT; … … 1789 4165 int ret; 1790 4166 4167 (void) grdstp; /* unused */ 4168 1791 4169 if (!b->fns->_nss_getgrent_r) { 1792 4170 return ENOENT; … … 1824 4202 } 1825 4203 1826 /* 1827 * PUBLIC interface1828 * /1829 1830 _PUBLIC_struct passwd *nwrap_getpwnam(const char *name)4204 /**************************************************************************** 4205 * GETPWNAM 4206 ***************************************************************************/ 4207 4208 static struct passwd *nwrap_getpwnam(const char *name) 1831 4209 { 1832 4210 int i; 1833 4211 struct passwd *pwd; 1834 1835 if (!nwrap_enabled()) {1836 return real_getpwnam(name);1837 }1838 4212 1839 4213 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 1848 4222 } 1849 4223 1850 _PUBLIC_ int nwrap_getpwnam_r(const char *name, struct passwd *pwdst, 1851 char *buf, size_t buflen, struct passwd **pwdstp) 4224 struct passwd *getpwnam(const char *name) 4225 { 4226 if (!nss_wrapper_enabled()) { 4227 return libc_getpwnam(name); 4228 } 4229 4230 return nwrap_getpwnam(name); 4231 } 4232 4233 /**************************************************************************** 4234 * GETPWNAM_R 4235 ***************************************************************************/ 4236 4237 static int nwrap_getpwnam_r(const char *name, struct passwd *pwdst, 4238 char *buf, size_t buflen, struct passwd **pwdstp) 1852 4239 { 1853 4240 int i,ret; 1854 1855 if (!nwrap_enabled()) {1856 return real_getpwnam_r(name, pwdst, buf, buflen, pwdstp);1857 }1858 4241 1859 4242 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 1869 4252 } 1870 4253 1871 _PUBLIC_ struct passwd *nwrap_getpwuid(uid_t uid) 4254 #ifdef HAVE_GETPWNAM_R 4255 # ifdef HAVE_SOLARIS_GETPWNAM_R 4256 int getpwnam_r(const char *name, struct passwd *pwdst, 4257 char *buf, int buflen, struct passwd **pwdstp) 4258 # else /* HAVE_SOLARIS_GETPWNAM_R */ 4259 int getpwnam_r(const char *name, struct passwd *pwdst, 4260 char *buf, size_t buflen, struct passwd **pwdstp) 4261 # endif /* HAVE_SOLARIS_GETPWNAM_R */ 4262 { 4263 if (!nss_wrapper_enabled()) { 4264 return libc_getpwnam_r(name, pwdst, buf, buflen, pwdstp); 4265 } 4266 4267 return nwrap_getpwnam_r(name, pwdst, buf, buflen, pwdstp); 4268 } 4269 #endif 4270 4271 /**************************************************************************** 4272 * GETPWUID 4273 ***************************************************************************/ 4274 4275 static struct passwd *nwrap_getpwuid(uid_t uid) 1872 4276 { 1873 4277 int i; 1874 4278 struct passwd *pwd; 1875 1876 if (!nwrap_enabled()) {1877 return real_getpwuid(uid);1878 }1879 4279 1880 4280 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 1889 4289 } 1890 4290 1891 _PUBLIC_ int nwrap_getpwuid_r(uid_t uid, struct passwd *pwdst, 1892 char *buf, size_t buflen, struct passwd **pwdstp) 4291 struct passwd *getpwuid(uid_t uid) 4292 { 4293 if (!nss_wrapper_enabled()) { 4294 return libc_getpwuid(uid); 4295 } 4296 4297 return nwrap_getpwuid(uid); 4298 } 4299 4300 /**************************************************************************** 4301 * GETPWUID_R 4302 ***************************************************************************/ 4303 4304 static int nwrap_getpwuid_r(uid_t uid, struct passwd *pwdst, 4305 char *buf, size_t buflen, struct passwd **pwdstp) 1893 4306 { 1894 4307 int i,ret; 1895 1896 if (!nwrap_enabled()) {1897 return real_getpwuid_r(uid, pwdst, buf, buflen, pwdstp);1898 }1899 4308 1900 4309 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 1910 4319 } 1911 4320 1912 _PUBLIC_ void nwrap_setpwent(void) 4321 #ifdef HAVE_SOLARIS_GETPWUID_R 4322 int getpwuid_r(uid_t uid, struct passwd *pwdst, 4323 char *buf, int buflen, struct passwd **pwdstp) 4324 #else 4325 int getpwuid_r(uid_t uid, struct passwd *pwdst, 4326 char *buf, size_t buflen, struct passwd **pwdstp) 4327 #endif 4328 { 4329 if (!nss_wrapper_enabled()) { 4330 return libc_getpwuid_r(uid, pwdst, buf, buflen, pwdstp); 4331 } 4332 4333 return nwrap_getpwuid_r(uid, pwdst, buf, buflen, pwdstp); 4334 } 4335 4336 /**************************************************************************** 4337 * SETPWENT 4338 ***************************************************************************/ 4339 4340 static void nwrap_setpwent(void) 1913 4341 { 1914 4342 int i; 1915 1916 if (!nwrap_enabled()) {1917 real_setpwent();1918 return;1919 }1920 4343 1921 4344 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 1925 4348 } 1926 4349 1927 _PUBLIC_ struct passwd *nwrap_getpwent(void) 4350 void setpwent(void) 4351 { 4352 if (!nss_wrapper_enabled()) { 4353 libc_setpwent(); 4354 return; 4355 } 4356 4357 nwrap_setpwent(); 4358 } 4359 4360 /**************************************************************************** 4361 * GETPWENT 4362 ***************************************************************************/ 4363 4364 static struct passwd *nwrap_getpwent(void) 1928 4365 { 1929 4366 int i; 1930 4367 struct passwd *pwd; 1931 1932 if (!nwrap_enabled()) {1933 return real_getpwent();1934 }1935 4368 1936 4369 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 1945 4378 } 1946 4379 1947 _PUBLIC_ int nwrap_getpwent_r(struct passwd *pwdst, char *buf, 1948 size_t buflen, struct passwd **pwdstp) 4380 struct passwd *getpwent(void) 4381 { 4382 if (!nss_wrapper_enabled()) { 4383 return libc_getpwent(); 4384 } 4385 4386 return nwrap_getpwent(); 4387 } 4388 4389 /**************************************************************************** 4390 * GETPWENT_R 4391 ***************************************************************************/ 4392 4393 static int nwrap_getpwent_r(struct passwd *pwdst, char *buf, 4394 size_t buflen, struct passwd **pwdstp) 1949 4395 { 1950 4396 int i,ret; 1951 1952 if (!nwrap_enabled()) {1953 #ifdef SOLARIS_GETPWENT_R1954 struct passwd *pw;1955 pw = real_getpwent_r(pwdst, buf, buflen);1956 if (!pw) {1957 if (errno == 0) {1958 return ENOENT;1959 }1960 return errno;1961 }1962 if (pwdstp) {1963 *pwdstp = pw;1964 }1965 return 0;1966 #else1967 return real_getpwent_r(pwdst, buf, buflen, pwdstp);1968 #endif1969 }1970 4397 1971 4398 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 1981 4408 } 1982 4409 1983 _PUBLIC_ void nwrap_endpwent(void) 4410 #ifdef HAVE_SOLARIS_GETPWENT_R 4411 struct passwd *getpwent_r(struct passwd *pwdst, char *buf, int buflen) 4412 { 4413 struct passwd *pwdstp = NULL; 4414 int rc; 4415 4416 if (!nss_wrapper_enabled()) { 4417 return libc_getpwent_r(pwdst, buf, buflen); 4418 } 4419 rc = nwrap_getpwent_r(pwdst, buf, buflen, &pwdstp); 4420 if (rc < 0) { 4421 return NULL; 4422 } 4423 4424 return pwdstp; 4425 } 4426 #else /* HAVE_SOLARIS_GETPWENT_R */ 4427 int getpwent_r(struct passwd *pwdst, char *buf, 4428 size_t buflen, struct passwd **pwdstp) 4429 { 4430 if (!nss_wrapper_enabled()) { 4431 return libc_getpwent_r(pwdst, buf, buflen, pwdstp); 4432 } 4433 4434 return nwrap_getpwent_r(pwdst, buf, buflen, pwdstp); 4435 } 4436 #endif /* HAVE_SOLARIS_GETPWENT_R */ 4437 4438 /**************************************************************************** 4439 * ENDPWENT 4440 ***************************************************************************/ 4441 4442 static void nwrap_endpwent(void) 1984 4443 { 1985 4444 int i; 1986 1987 if (!nwrap_enabled()) {1988 real_endpwent();1989 return;1990 }1991 4445 1992 4446 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 1996 4450 } 1997 4451 1998 _PUBLIC_ int nwrap_initgroups(const char *user, gid_t group) 4452 void endpwent(void) 4453 { 4454 if (!nss_wrapper_enabled()) { 4455 libc_endpwent(); 4456 return; 4457 } 4458 4459 nwrap_endpwent(); 4460 } 4461 4462 /**************************************************************************** 4463 * INITGROUPS 4464 ***************************************************************************/ 4465 4466 static int nwrap_initgroups(const char *user, gid_t group) 1999 4467 { 2000 4468 int i; 2001 2002 if (!nwrap_enabled()) {2003 return real_initgroups(user, group);2004 }2005 4469 2006 4470 for (i=0; i < nwrap_main_global->num_backends; i++) { 2007 4471 struct nwrap_backend *b = &nwrap_main_global->backends[i]; 2008 return b->ops->nw_initgroups(b, user, group); 4472 int rc; 4473 4474 rc = b->ops->nw_initgroups(b, user, group); 4475 if (rc == 0) { 4476 return 0; 4477 } 2009 4478 } 2010 4479 … … 2013 4482 } 2014 4483 2015 _PUBLIC_ struct group *nwrap_getgrnam(const char *name) 4484 int initgroups(const char *user, gid_t group) 4485 { 4486 if (!nss_wrapper_enabled()) { 4487 return libc_initgroups(user, group); 4488 } 4489 4490 return nwrap_initgroups(user, group); 4491 } 4492 4493 /**************************************************************************** 4494 * GETGRNAM 4495 ***************************************************************************/ 4496 4497 static struct group *nwrap_getgrnam(const char *name) 2016 4498 { 2017 4499 int i; 2018 4500 struct group *grp; 2019 2020 if (!nwrap_enabled()) {2021 return real_getgrnam(name);2022 }2023 4501 2024 4502 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 2033 4511 } 2034 4512 2035 _PUBLIC_ int nwrap_getgrnam_r(const char *name, struct group *grdst, 2036 char *buf, size_t buflen, struct group **grdstp) 2037 { 2038 int i,ret; 2039 2040 if (!nwrap_enabled()) { 2041 return real_getgrnam_r(name, grdst, buf, buflen, grdstp); 2042 } 4513 struct group *getgrnam(const char *name) 4514 { 4515 if (!nss_wrapper_enabled()) { 4516 return libc_getgrnam(name); 4517 } 4518 4519 return nwrap_getgrnam(name); 4520 } 4521 4522 /**************************************************************************** 4523 * GETGRNAM_R 4524 ***************************************************************************/ 4525 4526 static int nwrap_getgrnam_r(const char *name, struct group *grdst, 4527 char *buf, size_t buflen, struct group **grdstp) 4528 { 4529 int i, ret; 2043 4530 2044 4531 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 2054 4541 } 2055 4542 2056 _PUBLIC_ struct group *nwrap_getgrgid(gid_t gid) 4543 #ifdef HAVE_GETGRNAM_R 4544 # ifdef HAVE_SOLARIS_GETGRNAM_R 4545 int getgrnam_r(const char *name, struct group *grp, 4546 char *buf, int buflen, struct group **pgrp) 4547 # else /* HAVE_SOLARIS_GETGRNAM_R */ 4548 int getgrnam_r(const char *name, struct group *grp, 4549 char *buf, size_t buflen, struct group **pgrp) 4550 # endif /* HAVE_SOLARIS_GETGRNAM_R */ 4551 { 4552 if (!nss_wrapper_enabled()) { 4553 return libc_getgrnam_r(name, 4554 grp, 4555 buf, 4556 buflen, 4557 pgrp); 4558 } 4559 4560 return nwrap_getgrnam_r(name, grp, buf, buflen, pgrp); 4561 } 4562 #endif /* HAVE_GETGRNAM_R */ 4563 4564 /**************************************************************************** 4565 * GETGRGID 4566 ***************************************************************************/ 4567 4568 static struct group *nwrap_getgrgid(gid_t gid) 2057 4569 { 2058 4570 int i; 2059 4571 struct group *grp; 2060 2061 if (!nwrap_enabled()) {2062 return real_getgrgid(gid);2063 }2064 4572 2065 4573 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 2074 4582 } 2075 4583 2076 _PUBLIC_ int nwrap_getgrgid_r(gid_t gid, struct group *grdst, 2077 char *buf, size_t buflen, struct group **grdstp) 4584 struct group *getgrgid(gid_t gid) 4585 { 4586 if (!nss_wrapper_enabled()) { 4587 return libc_getgrgid(gid); 4588 } 4589 4590 return nwrap_getgrgid(gid); 4591 } 4592 4593 /**************************************************************************** 4594 * GETGRGID_R 4595 ***************************************************************************/ 4596 4597 static int nwrap_getgrgid_r(gid_t gid, struct group *grdst, 4598 char *buf, size_t buflen, struct group **grdstp) 2078 4599 { 2079 4600 int i,ret; 2080 2081 if (!nwrap_enabled()) {2082 return real_getgrgid_r(gid, grdst, buf, buflen, grdstp);2083 }2084 4601 2085 4602 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 2095 4612 } 2096 4613 2097 _PUBLIC_ void nwrap_setgrent(void) 4614 #ifdef HAVE_GETGRGID_R 4615 # ifdef HAVE_SOLARIS_GETGRGID_R 4616 int getgrgid_r(gid_t gid, struct group *grdst, 4617 char *buf, int buflen, struct group **grdstp) 4618 # else /* HAVE_SOLARIS_GETGRGID_R */ 4619 int getgrgid_r(gid_t gid, struct group *grdst, 4620 char *buf, size_t buflen, struct group **grdstp) 4621 # endif /* HAVE_SOLARIS_GETGRGID_R */ 4622 { 4623 if (!nss_wrapper_enabled()) { 4624 return libc_getgrgid_r(gid, grdst, buf, buflen, grdstp); 4625 } 4626 4627 return nwrap_getgrgid_r(gid, grdst, buf, buflen, grdstp); 4628 } 4629 #endif 4630 4631 /**************************************************************************** 4632 * SETGRENT 4633 ***************************************************************************/ 4634 4635 static void nwrap_setgrent(void) 2098 4636 { 2099 4637 int i; 2100 2101 if (!nwrap_enabled()) {2102 real_setgrent();2103 return;2104 }2105 4638 2106 4639 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 2110 4643 } 2111 4644 2112 _PUBLIC_ struct group *nwrap_getgrent(void) 4645 #ifdef HAVE_BSD_SETGRENT 4646 int setgrent(void) 4647 #else 4648 void setgrent(void) 4649 #endif 4650 { 4651 if (!nss_wrapper_enabled()) { 4652 libc_setgrent(); 4653 goto out; 4654 } 4655 4656 nwrap_setgrent(); 4657 4658 out: 4659 #ifdef HAVE_BSD_SETGRENT 4660 return 0; 4661 #else 4662 return; 4663 #endif 4664 } 4665 4666 /**************************************************************************** 4667 * GETGRENT 4668 ***************************************************************************/ 4669 4670 static struct group *nwrap_getgrent(void) 2113 4671 { 2114 4672 int i; 2115 4673 struct group *grp; 2116 2117 if (!nwrap_enabled()) {2118 return real_getgrent();2119 }2120 4674 2121 4675 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 2130 4684 } 2131 4685 2132 _PUBLIC_ int nwrap_getgrent_r(struct group *grdst, char *buf, 2133 size_t buflen, struct group **grdstp) 4686 struct group *getgrent(void) 4687 { 4688 if (!nss_wrapper_enabled()) { 4689 return libc_getgrent(); 4690 } 4691 4692 return nwrap_getgrent(); 4693 } 4694 4695 /**************************************************************************** 4696 * GETGRENT_R 4697 ***************************************************************************/ 4698 4699 static int nwrap_getgrent_r(struct group *grdst, char *buf, 4700 size_t buflen, struct group **grdstp) 2134 4701 { 2135 4702 int i,ret; 2136 2137 if (!nwrap_enabled()) {2138 #ifdef SOLARIS_GETGRENT_R2139 struct group *gr;2140 gr = real_getgrent_r(grdst, buf, buflen);2141 if (!gr) {2142 if (errno == 0) {2143 return ENOENT;2144 }2145 return errno;2146 }2147 if (grdstp) {2148 *grdstp = gr;2149 }2150 return 0;2151 #else2152 return real_getgrent_r(grdst, buf, buflen, grdstp);2153 #endif2154 }2155 4703 2156 4704 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 2166 4714 } 2167 4715 2168 _PUBLIC_ void nwrap_endgrent(void) 4716 #ifdef HAVE_SOLARIS_GETGRENT_R 4717 struct group *getgrent_r(struct group *src, char *buf, int buflen) 4718 { 4719 struct group *grdstp = NULL; 4720 int rc; 4721 4722 if (!nss_wrapper_enabled()) { 4723 return libc_getgrent_r(src, buf, buflen); 4724 } 4725 4726 rc = nwrap_getgrent_r(src, buf, buflen, &grdstp); 4727 if (rc < 0) { 4728 return NULL; 4729 } 4730 4731 return grdstp; 4732 } 4733 #else /* HAVE_SOLARIS_GETGRENT_R */ 4734 int getgrent_r(struct group *src, char *buf, 4735 size_t buflen, struct group **grdstp) 4736 { 4737 if (!nss_wrapper_enabled()) { 4738 return libc_getgrent_r(src, buf, buflen, grdstp); 4739 } 4740 4741 return nwrap_getgrent_r(src, buf, buflen, grdstp); 4742 } 4743 #endif /* HAVE_SOLARIS_GETGRENT_R */ 4744 4745 /**************************************************************************** 4746 * ENDGRENT 4747 ***************************************************************************/ 4748 4749 static void nwrap_endgrent(void) 2169 4750 { 2170 4751 int i; 2171 2172 if (!nwrap_enabled()) {2173 real_endgrent();2174 return;2175 }2176 4752 2177 4753 for (i=0; i < nwrap_main_global->num_backends; i++) { … … 2181 4757 } 2182 4758 2183 _PUBLIC_ int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups) 4759 void endgrent(void) 4760 { 4761 if (!nss_wrapper_enabled()) { 4762 libc_endgrent(); 4763 return; 4764 } 4765 4766 nwrap_endgrent(); 4767 } 4768 4769 /**************************************************************************** 4770 * GETGROUPLIST 4771 ***************************************************************************/ 4772 4773 #ifdef HAVE_GETGROUPLIST 4774 static int nwrap_getgrouplist(const char *user, gid_t group, 4775 gid_t *groups, int *ngroups) 2184 4776 { 2185 4777 struct group *grp; 2186 4778 gid_t *groups_tmp; 2187 4779 int count = 1; 2188 const char *name_of_group = ""; 2189 2190 if (!nwrap_enabled()) { 2191 return real_getgrouplist(user, group, groups, ngroups); 2192 } 2193 2194 NWRAP_DEBUG(("%s: getgrouplist called for %s\n", __location__, user)); 4780 4781 NWRAP_LOG(NWRAP_LOG_DEBUG, "getgrouplist called for %s", user); 2195 4782 2196 4783 groups_tmp = (gid_t *)malloc(count * sizeof(gid_t)); 2197 4784 if (!groups_tmp) { 2198 NWRAP_ ERROR(("%s:calloc failed\n",__location__));4785 NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory"); 2199 4786 errno = ENOMEM; 2200 4787 return -1; 2201 4788 } 2202 2203 memcpy(groups_tmp, &group, sizeof(gid_t)); 2204 2205 grp = nwrap_getgrgid(group); 2206 if (grp) { 2207 name_of_group = grp->gr_name; 2208 } 4789 groups_tmp[0] = group; 2209 4790 2210 4791 nwrap_setgrent(); … … 2212 4793 int i = 0; 2213 4794 2214 NWRAP_VERBOSE(("%s: inspecting %s for group membership\n", 2215 __location__, grp->gr_name)); 4795 NWRAP_LOG(NWRAP_LOG_DEBUG, 4796 "Inspecting %s for group membership", 4797 grp->gr_name); 2216 4798 2217 4799 for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) { 2218 4800 2219 if ((strcmp(user, grp->gr_mem[i]) == 0) && 2220 (strcmp(name_of_group, grp->gr_name) != 0)) { 2221 2222 NWRAP_DEBUG(("%s: %s is member of %s\n", 2223 __location__, user, grp->gr_name)); 4801 if (group != grp->gr_gid && 4802 (strcmp(user, grp->gr_mem[i]) == 0)) { 4803 4804 NWRAP_LOG(NWRAP_LOG_DEBUG, 4805 "%s is member of %s", 4806 user, 4807 grp->gr_name); 2224 4808 2225 4809 groups_tmp = (gid_t *)realloc(groups_tmp, (count + 1) * sizeof(gid_t)); 2226 4810 if (!groups_tmp) { 2227 NWRAP_ERROR(("%s:calloc failed\n",__location__)); 4811 NWRAP_LOG(NWRAP_LOG_ERROR, 4812 "Out of memory"); 2228 4813 errno = ENOMEM; 2229 4814 return -1; 2230 4815 } 2231 2232 memcpy(&groups_tmp[count], &grp->gr_gid, sizeof(gid_t)); 4816 groups_tmp[count] = grp->gr_gid; 4817 2233 4818 count++; 2234 4819 } … … 2238 4823 nwrap_endgrent(); 2239 4824 2240 NWRAP_VERBOSE(("%s: %s is member of %d groups: %d\n", 2241 __location__, user, *ngroups)); 4825 NWRAP_LOG(NWRAP_LOG_DEBUG, 4826 "%s is member of %d groups", 4827 user, *ngroups); 2242 4828 2243 4829 if (*ngroups < count) { … … 2253 4839 return count; 2254 4840 } 4841 4842 int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups) 4843 { 4844 if (!nss_wrapper_enabled()) { 4845 return libc_getgrouplist(user, group, groups, ngroups); 4846 } 4847 4848 return nwrap_getgrouplist(user, group, groups, ngroups); 4849 } 4850 #endif 4851 4852 /********************************************************** 4853 * SHADOW 4854 **********************************************************/ 4855 4856 #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) 4857 4858 #ifdef HAVE_SETSPENT 4859 static void nwrap_setspent(void) 4860 { 4861 nwrap_files_setspent(); 4862 } 4863 4864 void setspent(void) 4865 { 4866 if (!nss_wrapper_shadow_enabled()) { 4867 return; 4868 } 4869 4870 nwrap_setspent(); 4871 } 4872 4873 static struct spwd *nwrap_getspent(void) 4874 { 4875 return nwrap_files_getspent(); 4876 } 4877 4878 struct spwd *getspent(void) 4879 { 4880 if (!nss_wrapper_shadow_enabled()) { 4881 return NULL; 4882 } 4883 4884 return nwrap_getspent(); 4885 } 4886 4887 static void nwrap_endspent(void) 4888 { 4889 nwrap_files_endspent(); 4890 } 4891 4892 void endspent(void) 4893 { 4894 if (!nss_wrapper_shadow_enabled()) { 4895 return; 4896 } 4897 4898 nwrap_endspent(); 4899 } 4900 #endif /* HAVE_SETSPENT */ 4901 4902 static struct spwd *nwrap_getspnam(const char *name) 4903 { 4904 return nwrap_files_getspnam(name); 4905 } 4906 4907 struct spwd *getspnam(const char *name) 4908 { 4909 if (!nss_wrapper_shadow_enabled()) { 4910 return NULL; 4911 } 4912 4913 return nwrap_getspnam(name); 4914 } 4915 4916 #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ 4917 4918 /********************************************************** 4919 * NETDB 4920 **********************************************************/ 4921 4922 static void nwrap_sethostent(int stayopen) { 4923 (void) stayopen; /* ignored */ 4924 4925 nwrap_files_sethostent(); 4926 } 4927 4928 #ifdef HAVE_SOLARIS_SETHOSTENT 4929 int sethostent(int stayopen) 4930 { 4931 if (!nss_wrapper_hosts_enabled()) { 4932 libc_sethostent(stayopen); 4933 return 0; 4934 } 4935 4936 nwrap_sethostent(stayopen); 4937 4938 return 0; 4939 } 4940 #else /* HAVE_SOLARIS_SETHOSTENT */ 4941 void sethostent(int stayopen) 4942 { 4943 if (!nss_wrapper_hosts_enabled()) { 4944 libc_sethostent(stayopen); 4945 return; 4946 } 4947 4948 nwrap_sethostent(stayopen); 4949 } 4950 #endif /* HAVE_SOLARIS_SETHOSTENT */ 4951 4952 static struct hostent *nwrap_gethostent(void) 4953 { 4954 return nwrap_files_gethostent(); 4955 } 4956 4957 struct hostent *gethostent(void) { 4958 if (!nss_wrapper_hosts_enabled()) { 4959 return libc_gethostent(); 4960 } 4961 4962 return nwrap_gethostent(); 4963 } 4964 4965 static void nwrap_endhostent(void) { 4966 nwrap_files_endhostent(); 4967 } 4968 4969 #ifdef HAVE_SOLARIS_ENDHOSTENT 4970 int endhostent(void) 4971 { 4972 if (!nss_wrapper_hosts_enabled()) { 4973 libc_endhostent(); 4974 return 0; 4975 } 4976 4977 nwrap_endhostent(); 4978 4979 return 0; 4980 } 4981 #else /* HAVE_SOLARIS_ENDHOSTENT */ 4982 void endhostent(void) 4983 { 4984 if (!nss_wrapper_hosts_enabled()) { 4985 libc_endhostent(); 4986 return; 4987 } 4988 4989 nwrap_endhostent(); 4990 } 4991 #endif /* HAVE_SOLARIS_ENDHOSTENT */ 4992 4993 #ifdef BSD 4994 /* BSD implementation stores data in thread local storage but GLIBC does not */ 4995 static __thread struct hostent user_he; 4996 static __thread struct nwrap_vector user_addrlist; 4997 #else 4998 static struct hostent user_he; 4999 static struct nwrap_vector user_addrlist; 5000 #endif /* BSD */ 5001 static struct hostent *nwrap_gethostbyname(const char *name) 5002 { 5003 if (nwrap_files_gethostbyname(name, AF_UNSPEC, &user_he, &user_addrlist) == -1) { 5004 return NULL; 5005 } 5006 return &user_he; 5007 } 5008 5009 struct hostent *gethostbyname(const char *name) 5010 { 5011 if (!nss_wrapper_hosts_enabled()) { 5012 return libc_gethostbyname(name); 5013 } 5014 5015 return nwrap_gethostbyname(name); 5016 } 5017 5018 /* This is a GNU extension - Also can be found on BSD systems */ 5019 #ifdef HAVE_GETHOSTBYNAME2 5020 #ifdef BSD 5021 /* BSD implementation stores data in thread local storage but GLIBC not */ 5022 static __thread struct hostent user_he2; 5023 static __thread struct nwrap_vector user_addrlist2; 5024 #else 5025 static struct hostent user_he2; 5026 static struct nwrap_vector user_addrlist2; 5027 #endif /* BSD */ 5028 static struct hostent *nwrap_gethostbyname2(const char *name, int af) 5029 { 5030 if (nwrap_files_gethostbyname(name, af, &user_he2, &user_addrlist2) == -1) { 5031 return NULL; 5032 } 5033 return &user_he2; 5034 } 5035 5036 struct hostent *gethostbyname2(const char *name, int af) 5037 { 5038 if (!nss_wrapper_hosts_enabled()) { 5039 return libc_gethostbyname2(name, af); 5040 } 5041 5042 return nwrap_gethostbyname2(name, af); 5043 } 5044 #endif 5045 5046 static struct hostent *nwrap_gethostbyaddr(const void *addr, 5047 socklen_t len, int type) 5048 { 5049 return nwrap_files_gethostbyaddr(addr, len, type); 5050 } 5051 5052 struct hostent *gethostbyaddr(const void *addr, 5053 socklen_t len, int type) 5054 { 5055 if (!nss_wrapper_hosts_enabled()) { 5056 return libc_gethostbyaddr(addr, len, type); 5057 } 5058 5059 return nwrap_gethostbyaddr(addr, len, type); 5060 } 5061 5062 static const struct addrinfo default_hints = 5063 { 5064 .ai_flags = AI_ADDRCONFIG|AI_V4MAPPED, 5065 .ai_family = AF_UNSPEC, 5066 .ai_socktype = 0, 5067 .ai_protocol = 0, 5068 .ai_addrlen = 0, 5069 .ai_addr = NULL, 5070 .ai_canonname = NULL, 5071 .ai_next = NULL 5072 }; 5073 5074 static int nwrap_convert_he_ai(const struct hostent *he, 5075 unsigned short port, 5076 const struct addrinfo *hints, 5077 struct addrinfo **pai, 5078 bool skip_canonname) 5079 { 5080 struct addrinfo *ai; 5081 socklen_t socklen; 5082 5083 if (he == NULL) { 5084 return EAI_MEMORY; 5085 } 5086 5087 switch (he->h_addrtype) { 5088 case AF_INET: 5089 socklen = sizeof(struct sockaddr_in); 5090 break; 5091 #ifdef HAVE_IPV6 5092 case AF_INET6: 5093 socklen = sizeof(struct sockaddr_in6); 5094 break; 5095 #endif 5096 default: 5097 return EAI_FAMILY; 5098 } 5099 5100 ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + socklen); 5101 if (ai == NULL) { 5102 return EAI_MEMORY; 5103 } 5104 5105 ai->ai_flags = hints->ai_flags; 5106 ai->ai_family = he->h_addrtype; 5107 ai->ai_socktype = hints->ai_socktype; 5108 ai->ai_protocol = hints->ai_protocol; 5109 ai->ai_canonname = NULL; 5110 5111 if (ai->ai_socktype == 0) { 5112 ai->ai_socktype = SOCK_DGRAM; 5113 } 5114 if (ai->ai_protocol == 0) { 5115 if (ai->ai_socktype == SOCK_DGRAM) { 5116 ai->ai_protocol = IPPROTO_UDP; 5117 } else if (ai->ai_socktype == SOCK_STREAM) { 5118 ai->ai_protocol = IPPROTO_TCP; 5119 } 5120 } 5121 5122 ai->ai_addrlen = socklen; 5123 ai->ai_addr = (void *)(ai + 1); 5124 5125 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 5126 ai->ai_addr->sa_len = socklen; 5127 #endif 5128 ai->ai_addr->sa_family = he->h_addrtype; 5129 5130 switch (he->h_addrtype) { 5131 case AF_INET: 5132 { 5133 struct sockaddr_in *sinp = 5134 (struct sockaddr_in *) ai->ai_addr; 5135 5136 memset(sinp, 0, sizeof(struct sockaddr_in)); 5137 5138 sinp->sin_port = htons(port); 5139 sinp->sin_family = AF_INET; 5140 5141 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero)); 5142 memcpy(&sinp->sin_addr, he->h_addr_list[0], he->h_length); 5143 5144 } 5145 break; 5146 #ifdef HAVE_IPV6 5147 case AF_INET6: 5148 { 5149 struct sockaddr_in6 *sin6p = 5150 (struct sockaddr_in6 *) ai->ai_addr; 5151 5152 memset(sin6p, 0, sizeof(struct sockaddr_in6)); 5153 5154 sin6p->sin6_port = htons(port); 5155 sin6p->sin6_family = AF_INET6; 5156 5157 memcpy(&sin6p->sin6_addr, 5158 he->h_addr_list[0], 5159 he->h_length); 5160 } 5161 break; 5162 #endif 5163 } 5164 5165 ai->ai_next = NULL; 5166 5167 if (he->h_name && !skip_canonname) { 5168 ai->ai_canonname = strdup(he->h_name); 5169 if (ai->ai_canonname == NULL) { 5170 freeaddrinfo(ai); 5171 return EAI_MEMORY; 5172 } 5173 } 5174 5175 *pai = ai; 5176 return 0; 5177 } 5178 5179 static int nwrap_getaddrinfo(const char *node, 5180 const char *service, 5181 const struct addrinfo *hints, 5182 struct addrinfo **res) 5183 { 5184 struct addrinfo *ai = NULL; 5185 unsigned short port = 0; 5186 struct { 5187 int family; 5188 union { 5189 struct in_addr v4; 5190 #ifdef HAVE_IPV6 5191 struct in6_addr v6; 5192 } in; 5193 #endif 5194 } addr = { 5195 .family = AF_UNSPEC, 5196 }; 5197 int rc; 5198 5199 if (node == NULL && service == NULL) { 5200 return EAI_NONAME; 5201 } 5202 5203 if (hints == NULL) { 5204 hints = &default_hints; 5205 } 5206 5207 /* EAI_BADFLAGS 5208 hints.ai_flags contains invalid flags; or, hints.ai_flags 5209 included AI_CANONNAME and name was NULL. 5210 */ 5211 if ((hints->ai_flags & AI_CANONNAME) && (node == NULL)) { 5212 return EAI_BADFLAGS; 5213 } 5214 5215 /* If no node has been specified, let glibc deal with it */ 5216 if (node == NULL) { 5217 int ret; 5218 struct addrinfo *p = NULL; 5219 5220 ret = libc_getaddrinfo(node, service, hints, &p); 5221 5222 if (ret == 0) { 5223 *res = p; 5224 } 5225 return ret; 5226 } 5227 5228 if (service != NULL && service[0] != '\0') { 5229 const char *proto = NULL; 5230 struct servent *s; 5231 char *end_ptr; 5232 long sl; 5233 5234 errno = 0; 5235 sl = strtol(service, &end_ptr, 10); 5236 5237 if (*end_ptr == '\0') { 5238 port = sl; 5239 goto valid_port; 5240 } else if (hints->ai_flags & AI_NUMERICSERV) { 5241 return EAI_NONAME; 5242 } 5243 5244 if (hints->ai_protocol != 0) { 5245 struct protoent *pent; 5246 5247 pent = getprotobynumber(hints->ai_protocol); 5248 if (pent != NULL) { 5249 proto = pent->p_name; 5250 } 5251 } 5252 5253 s = getservbyname(service, proto); 5254 if (s == NULL) { 5255 return EAI_NONAME; 5256 } 5257 port = ntohs(s->s_port); 5258 } 5259 5260 valid_port: 5261 5262 rc = inet_pton(AF_INET, node, &addr.in.v4); 5263 if (rc == 1) { 5264 addr.family = AF_INET; 5265 } 5266 #ifdef HAVE_IPV6 5267 if (addr.family == AF_UNSPEC) { 5268 rc = inet_pton(AF_INET6, node, &addr.in.v6); 5269 if (rc == 1) { 5270 addr.family = AF_INET6; 5271 } 5272 } 5273 #endif 5274 5275 if (addr.family == AF_UNSPEC) { 5276 if (hints->ai_flags & AI_NUMERICHOST) { 5277 return EAI_NONAME; 5278 } 5279 } else if ((hints->ai_family != AF_UNSPEC) && 5280 (hints->ai_family != addr.family)) 5281 { 5282 return EAI_ADDRFAMILY; 5283 } 5284 5285 rc = nwrap_files_getaddrinfo(node, port, hints, &ai); 5286 if (rc != 0) { 5287 int ret; 5288 struct addrinfo *p = NULL; 5289 5290 ret = libc_getaddrinfo(node, service, hints, &p); 5291 5292 if (ret == 0) { 5293 /* 5294 * nwrap_files_getaddrinfo failed, but libc was 5295 * successful -- use the result from libc. 5296 */ 5297 *res = p; 5298 return 0; 5299 } 5300 5301 return rc; 5302 } 5303 5304 /* 5305 * If the socktype was not specified, duplicate 5306 * each ai returned, so that we have variants for 5307 * both UDP and TCP. 5308 */ 5309 if (hints->ai_socktype == 0) { 5310 struct addrinfo *ai_cur; 5311 5312 /* freeaddrinfo() frees ai_canonname and ai so allocate them */ 5313 for (ai_cur = ai; ai_cur != NULL; ai_cur = ai_cur->ai_next) { 5314 struct addrinfo *ai_new; 5315 5316 /* duplicate the current entry */ 5317 5318 ai_new = malloc(sizeof(struct addrinfo)); 5319 if (ai_new == NULL) { 5320 freeaddrinfo(ai); 5321 return EAI_MEMORY; 5322 } 5323 5324 memcpy(ai_new, ai_cur, sizeof(struct addrinfo)); 5325 ai_new->ai_next = NULL; 5326 5327 /* We need a deep copy or freeaddrinfo() will blow up */ 5328 if (ai_cur->ai_canonname != NULL) { 5329 ai_new->ai_canonname = 5330 strdup(ai_cur->ai_canonname); 5331 } 5332 5333 if (ai_cur->ai_socktype == SOCK_DGRAM) { 5334 ai_new->ai_socktype = SOCK_STREAM; 5335 } else if (ai_cur->ai_socktype == SOCK_STREAM) { 5336 ai_new->ai_socktype = SOCK_DGRAM; 5337 } 5338 if (ai_cur->ai_protocol == IPPROTO_TCP) { 5339 ai_new->ai_protocol = IPPROTO_UDP; 5340 } else if (ai_cur->ai_protocol == IPPROTO_UDP) { 5341 ai_new->ai_protocol = IPPROTO_TCP; 5342 } 5343 5344 /* now insert the new entry */ 5345 5346 ai_new->ai_next = ai_cur->ai_next; 5347 ai_cur->ai_next = ai_new; 5348 5349 /* and move on (don't duplicate the new entry) */ 5350 5351 ai_cur = ai_new; 5352 } 5353 } 5354 5355 *res = ai; 5356 5357 return 0; 5358 } 5359 5360 int getaddrinfo(const char *node, const char *service, 5361 const struct addrinfo *hints, 5362 struct addrinfo **res) 5363 { 5364 if (!nss_wrapper_hosts_enabled()) { 5365 return libc_getaddrinfo(node, service, hints, res); 5366 } 5367 5368 return nwrap_getaddrinfo(node, service, hints, res); 5369 } 5370 5371 static int nwrap_getnameinfo(const struct sockaddr *sa, socklen_t salen, 5372 char *host, size_t hostlen, 5373 char *serv, size_t servlen, 5374 int flags) 5375 { 5376 struct hostent *he; 5377 struct servent *service; 5378 const char *proto; 5379 const void *addr; 5380 socklen_t addrlen; 5381 uint16_t port; 5382 sa_family_t type; 5383 5384 if (sa == NULL || salen < sizeof(sa_family_t)) { 5385 return EAI_FAMILY; 5386 } 5387 5388 if ((flags & NI_NAMEREQD) && host == NULL && serv == NULL) { 5389 return EAI_NONAME; 5390 } 5391 5392 type = sa->sa_family; 5393 switch (type) { 5394 case AF_INET: 5395 if (salen < sizeof(struct sockaddr_in)) 5396 return EAI_FAMILY; 5397 addr = &((const struct sockaddr_in *)sa)->sin_addr; 5398 addrlen = sizeof(((const struct sockaddr_in *)sa)->sin_addr); 5399 port = ntohs(((const struct sockaddr_in *)sa)->sin_port); 5400 break; 5401 #ifdef HAVE_IPV6 5402 case AF_INET6: 5403 if (salen < sizeof(struct sockaddr_in6)) 5404 return EAI_FAMILY; 5405 addr = &((const struct sockaddr_in6 *)sa)->sin6_addr; 5406 addrlen = sizeof(((const struct sockaddr_in6 *)sa)->sin6_addr); 5407 port = ntohs(((const struct sockaddr_in6 *)sa)->sin6_port); 5408 break; 5409 #endif 5410 default: 5411 return EAI_FAMILY; 5412 } 5413 5414 if (host != NULL) { 5415 he = NULL; 5416 if ((flags & NI_NUMERICHOST) == 0) { 5417 he = nwrap_files_gethostbyaddr(addr, addrlen, type); 5418 if ((flags & NI_NAMEREQD) && (he == NULL || he->h_name == NULL)) 5419 return EAI_NONAME; 5420 } 5421 if (he != NULL && he->h_name != NULL) { 5422 if (strlen(he->h_name) >= hostlen) 5423 return EAI_OVERFLOW; 5424 strcpy(host, he->h_name); 5425 if (flags & NI_NOFQDN) 5426 host[strcspn(host, ".")] = '\0'; 5427 } else { 5428 if (inet_ntop(type, addr, host, hostlen) == NULL) 5429 return (errno == ENOSPC) ? EAI_OVERFLOW : EAI_FAIL; 5430 } 5431 } 5432 5433 if (serv != NULL) { 5434 service = NULL; 5435 if ((flags & NI_NUMERICSERV) == 0) { 5436 proto = (flags & NI_DGRAM) ? "udp" : "tcp"; 5437 service = getservbyport(htons(port), proto); 5438 } 5439 if (service != NULL) { 5440 if (strlen(service->s_name) >= servlen) 5441 return EAI_OVERFLOW; 5442 strcpy(serv, service->s_name); 5443 } else { 5444 if (snprintf(serv, servlen, "%u", port) >= (int) servlen) 5445 return EAI_OVERFLOW; 5446 } 5447 } 5448 5449 return 0; 5450 } 5451 5452 #ifdef HAVE_LINUX_GETNAMEINFO 5453 int getnameinfo(const struct sockaddr *sa, socklen_t salen, 5454 char *host, socklen_t hostlen, 5455 char *serv, socklen_t servlen, 5456 int flags) 5457 #elif defined(HAVE_LINUX_GETNAMEINFO_UNSIGNED) 5458 int getnameinfo(const struct sockaddr *sa, socklen_t salen, 5459 char *host, socklen_t hostlen, 5460 char *serv, socklen_t servlen, 5461 unsigned int flags) 5462 #else 5463 int getnameinfo(const struct sockaddr *sa, socklen_t salen, 5464 char *host, size_t hostlen, 5465 char *serv, size_t servlen, 5466 int flags) 5467 #endif 5468 { 5469 if (!nss_wrapper_hosts_enabled()) { 5470 return libc_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); 5471 } 5472 5473 return nwrap_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); 5474 } 5475 5476 static int nwrap_gethostname(char *name, size_t len) 5477 { 5478 const char *hostname = getenv("NSS_WRAPPER_HOSTNAME"); 5479 5480 if (strlen(hostname) >= len) { 5481 errno = ENAMETOOLONG; 5482 return -1; 5483 } 5484 snprintf(name, len, "%s", hostname); 5485 5486 return 0; 5487 } 5488 5489 #ifdef HAVE_SOLARIS_GETHOSTNAME 5490 int gethostname(char *name, int len) 5491 #else /* HAVE_SOLARIS_GETHOSTNAME */ 5492 int gethostname(char *name, size_t len) 5493 #endif /* HAVE_SOLARIS_GETHOSTNAME */ 5494 { 5495 if (!nwrap_hostname_enabled()) { 5496 return libc_gethostname(name, len); 5497 } 5498 5499 return nwrap_gethostname(name, len); 5500 } 5501 5502 /**************************** 5503 * DESTRUCTOR 5504 ***************************/ 5505 5506 /* 5507 * This function is called when the library is unloaded and makes sure that 5508 * sockets get closed and the unix file for the socket are unlinked. 5509 */ 5510 void nwrap_destructor(void) 5511 { 5512 int i; 5513 5514 NWRAP_LOCK_ALL; 5515 if (nwrap_main_global != NULL) { 5516 struct nwrap_main *m = nwrap_main_global; 5517 5518 /* libc */ 5519 SAFE_FREE(m->libc->fns); 5520 if (m->libc->handle != NULL) { 5521 dlclose(m->libc->handle); 5522 } 5523 if (m->libc->nsl_handle != NULL) { 5524 dlclose(m->libc->nsl_handle); 5525 } 5526 if (m->libc->sock_handle != NULL) { 5527 dlclose(m->libc->sock_handle); 5528 } 5529 SAFE_FREE(m->libc); 5530 5531 /* backends */ 5532 for (i = 0; i < m->num_backends; i++) { 5533 struct nwrap_backend *b = &(m->backends[i]); 5534 5535 if (b->so_handle != NULL) { 5536 dlclose(b->so_handle); 5537 } 5538 SAFE_FREE(b->fns); 5539 } 5540 SAFE_FREE(m->backends); 5541 } 5542 5543 if (nwrap_pw_global.cache != NULL) { 5544 struct nwrap_cache *c = nwrap_pw_global.cache; 5545 5546 nwrap_files_cache_unload(c); 5547 if (c->fd >= 0) { 5548 fclose(c->fp); 5549 c->fd = -1; 5550 } 5551 5552 SAFE_FREE(nwrap_pw_global.list); 5553 nwrap_pw_global.num = 0; 5554 } 5555 5556 if (nwrap_gr_global.cache != NULL) { 5557 struct nwrap_cache *c = nwrap_gr_global.cache; 5558 5559 nwrap_files_cache_unload(c); 5560 if (c->fd >= 0) { 5561 fclose(c->fp); 5562 c->fd = -1; 5563 } 5564 5565 SAFE_FREE(nwrap_gr_global.list); 5566 nwrap_pw_global.num = 0; 5567 } 5568 5569 #if defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) 5570 if (nwrap_sp_global.cache != NULL) { 5571 struct nwrap_cache *c = nwrap_sp_global.cache; 5572 5573 nwrap_files_cache_unload(c); 5574 if (c->fd >= 0) { 5575 fclose(c->fp); 5576 c->fd = -1; 5577 } 5578 5579 nwrap_sp_global.num = 0; 5580 } 5581 #endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */ 5582 5583 if (nwrap_he_global.cache != NULL) { 5584 struct nwrap_cache *c = nwrap_he_global.cache; 5585 5586 nwrap_files_cache_unload(c); 5587 if (c->fd >= 0) { 5588 fclose(c->fp); 5589 c->fd = -1; 5590 } 5591 5592 nwrap_he_global.num = 0; 5593 } 5594 5595 free(user_addrlist.items); 5596 #ifdef HAVE_GETHOSTBYNAME2 5597 free(user_addrlist2.items); 5598 #endif 5599 5600 hdestroy(); 5601 NWRAP_UNLOCK_ALL; 5602 } -
vendor/current/lib/nss_wrapper/wscript
r740 r988 1 1 #!/usr/bin/env python 2 2 3 import Options3 import os 4 4 5 def set_options(opt): 6 gr = opt.option_group('developer options') 7 gr.add_option('--enable-nss-wrapper', 8 help=("Turn on nss wrapper library (default=no)"), 9 action="store_true", dest='enable_nss_wrapper', default=False) 5 VERSION="1.1.2" 10 6 11 7 def configure(conf): 12 if (Options.options.enable_nss_wrapper or13 Options.options.developer or14 Options.options.enable_selftest):15 conf.DEFINE('NSS_WRAPPER', 1)16 conf. ADD_GLOBAL_DEPENDENCY('nss_wrapper')8 if conf.CHECK_BUNDLED_SYSTEM('nss_wrapper', minversion=VERSION, set_target=False): 9 conf.DEFINE('USING_SYSTEM_NSS_WRAPPER', 1) 10 libnss_wrapper_so_path = 'libnss_wrapper.so' 11 else: 12 conf.CHECK_HEADERS('nss.h') 17 13 14 # check HAVE_GCC_THREAD_LOCAL_STORAGE 15 conf.CHECK_CODE(''' 16 __thread int tls; 17 18 int main(void) { 19 return 0; 20 } 21 ''', 22 'HAVE_GCC_THREAD_LOCAL_STORAGE', 23 addmain=False, 24 msg='Checking for thread local storage') 25 26 # check HAVE_DESTRUCTOR_ATTRIBUTE 27 conf.CHECK_CODE(''' 28 void test_destructor_attribute(void) __attribute__ ((destructor)); 29 30 void test_destructor_attribute(void) 31 { 32 return; 33 } 34 35 int main(void) { 36 return 0; 37 } 38 ''', 39 'HAVE_DESTRUCTOR_ATTRIBUTE', 40 addmain=False, 41 msg='Checking for library destructor support') 42 43 conf.CHECK_FUNCS('gethostbyaddr_r gethostbyname_r') 44 # Solaris 45 conf.CHECK_FUNCS('__posix_getpwnam_r __posix_getpwuid_r') 46 conf.CHECK_FUNCS('__posix_getgrgid_r __posix_getgrnam_r') 47 48 conf.CHECK_FUNCS_IN('nsl', 49 'gethostname', 50 checklibc=True, 51 headers='unistd.h') 52 53 # Prototype checks 54 conf.CHECK_C_PROTOTYPE('getpwent_r', 55 'struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)', 56 define='HAVE_SOLARIS_GETPWENT_R', headers='unistd.h pwd.h') 57 conf.CHECK_C_PROTOTYPE('getpwnam_r', 58 'int getpwnam_r(const char *name, struct passwd *pwd, char *buf, int buflen, struct passwd **ppwd)', 59 define='HAVE_SOLARIS_GETPWNAM_R', headers='unistd.h pwd.h') 60 conf.CHECK_C_PROTOTYPE('getpwuid_r', 61 'int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, int buflen, struct passwd **ppwd)', 62 define='HAVE_SOLARIS_GETPWUID_R', headers='unistd.h pwd.h') 63 conf.CHECK_C_PROTOTYPE('getgrent_r', 64 'struct group *getgrent_r(struct group *src, char *buf, int buflen)', 65 define='HAVE_SOLARIS_GETGRENT_R', headers='unistd.h grp.h') 66 conf.CHECK_C_PROTOTYPE('getgrnam_r', 67 'int getgrnam_r(const char *name, struct group *grp, char *buf, int buflen, struct group **pgrp)', 68 define='HAVE_SOLARIS_GETGRNAM_R', headers='unistd.h grp.h') 69 conf.CHECK_C_PROTOTYPE('getgrgid_r', 70 'int getgrgid_r(gid_t gid, struct group *grp, char *buf, int buflen, struct group **pgrp)', 71 define='HAVE_SOLARIS_GETGRGID_R', headers='unistd.h grp.h') 72 conf.CHECK_C_PROTOTYPE('sethostent', 73 'int sethostent(int stayopen)', 74 define='HAVE_SOLARIS_SETHOSTENT', headers='unistd.h netdb.h') 75 conf.CHECK_C_PROTOTYPE('endhostent', 76 'int endhostent(void)', 77 define='HAVE_SOLARIS_ENDHOSTENT', headers='unistd.h netdb.h') 78 conf.CHECK_C_PROTOTYPE('gethostname', 79 'int gethostname(char *name, int len)', 80 define='HAVE_SOLARIS_GETHOSTNAME', headers='unistd.h netdb.h') 81 conf.CHECK_C_PROTOTYPE('setgrent', 82 'int setgrent(void)', 83 define='HAVE_BSD_SETGRENT', headers='unistd.h grp.h') 84 conf.CHECK_C_PROTOTYPE('getnameinfo', 85 'int getnameinfo (const struct sockaddr *sa, socklen_t salen, char *host, socklen_t __hostlen, char *serv, socklen_t servlen, int flags)', 86 define='HAVE_LINUX_GETNAMEINFO', headers='unistd.h netdb.h') 87 conf.CHECK_C_PROTOTYPE('getnameinfo', 88 'int getnameinfo (const struct sockaddr *sa, socklen_t salen, char *host, socklen_t __hostlen, char *serv, socklen_t servlen, unsigned int flags)', 89 define='HAVE_LINUX_GETNAMEINFO_UNSIGNED', headers='unistd.h netdb.h') 90 91 # Create full path to nss_wrapper 92 srcdir = os.path.realpath(conf.srcdir) 93 libnss_wrapper_so_path = srcdir + '/bin/default/lib/nss_wrapper/libnss-wrapper.so' 94 95 conf.DEFINE('LIBNSS_WRAPPER_SO_PATH', libnss_wrapper_so_path) 96 conf.DEFINE('NSS_WRAPPER', 1) 97 98 def build(bld): 99 if bld.CONFIG_SET("HAVE_NSS_H") and not bld.CONFIG_SET("USING_SYSTEM_NSS_WRAPPER"): 100 # We need to do it this way or the library wont work. 101 # Using private_library=True will add symbol version which 102 # breaks preloading! 103 bld.SAMBA_LIBRARY('nss_wrapper', 104 source='nss_wrapper.c', 105 deps='dl', 106 install=False, 107 realname='libnss-wrapper.so')
Note:
See TracChangeset
for help on using the changeset viewer.