00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #undef DEVELOPER
00029
00030 #include <stdlib.h>
00031 #include <sys/types.h>
00032 #include <sys/param.h>
00033 #include <string.h>
00034 #include <pwd.h>
00035 #include "includes.h"
00036 #include <syslog.h>
00037 #if !defined(HPUX)
00038 #include <sys/syslog.h>
00039 #endif
00040 #include "winbind_nss_config.h"
00041
00042 #if defined(HAVE_NSS_COMMON_H) || defined(HPUX)
00043
00044 #undef NSS_DEBUG
00045
00046 #ifdef NSS_DEBUG
00047 #define NSS_DEBUG(str) syslog(LOG_DEBUG, "nss_winbind: %s", str);
00048 #else
00049 #define NSS_DEBUG(str) ;
00050 #endif
00051
00052 #define NSS_ARGS(args) ((nss_XbyY_args_t *)args)
00053
00054 #ifdef HPUX
00055
00056
00057
00058
00059
00060
00061
00062 struct nss_groupsbymem {
00063 const char *username;
00064 gid_t *gid_array;
00065 int maxgids;
00066 int force_slow_way;
00067 int (*str2ent)(const char *instr, int instr_len, void *ent,
00068 char *buffer, int buflen);
00069 nss_status_t (*process_cstr)(const char *instr, int instr_len,
00070 struct nss_groupsbymem *);
00071 int numgids;
00072 };
00073
00074 #endif
00075
00076 #define make_pwent_str(dest, src) \
00077 { \
00078 if((dest = get_static(buffer, buflen, strlen(src)+1)) == NULL) \
00079 { \
00080 *errnop = ERANGE; \
00081 NSS_DEBUG("ERANGE error"); \
00082 return NSS_STATUS_TRYAGAIN; \
00083 } \
00084 strcpy(dest, src); \
00085 }
00086
00087 static NSS_STATUS _nss_winbind_setpwent_solwrap (nss_backend_t* be, void* args)
00088 {
00089 NSS_DEBUG("_nss_winbind_setpwent_solwrap");
00090 return _nss_winbind_setpwent();
00091 }
00092
00093 static NSS_STATUS
00094 _nss_winbind_endpwent_solwrap (nss_backend_t * be, void *args)
00095 {
00096 NSS_DEBUG("_nss_winbind_endpwent_solwrap");
00097 return _nss_winbind_endpwent();
00098 }
00099
00100 static NSS_STATUS
00101 _nss_winbind_getpwent_solwrap (nss_backend_t* be, void *args)
00102 {
00103 NSS_STATUS ret;
00104 char* buffer = NSS_ARGS(args)->buf.buffer;
00105 int buflen = NSS_ARGS(args)->buf.buflen;
00106 struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
00107 int* errnop = &NSS_ARGS(args)->erange;
00108 char logmsg[80];
00109
00110 ret = _nss_winbind_getpwent_r(result, buffer,
00111 buflen, errnop);
00112
00113 if(ret == NSS_STATUS_SUCCESS)
00114 {
00115 snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning user: %s\n",
00116 result->pw_name);
00117 NSS_DEBUG(logmsg);
00118 NSS_ARGS(args)->returnval = (void*) result;
00119 } else {
00120 snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning error: %d.\n",ret);
00121 NSS_DEBUG(logmsg);
00122 }
00123
00124 return ret;
00125 }
00126
00127 static NSS_STATUS
00128 _nss_winbind_getpwnam_solwrap (nss_backend_t* be, void* args)
00129 {
00130 NSS_STATUS ret;
00131 struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
00132
00133 NSS_DEBUG("_nss_winbind_getpwnam_solwrap");
00134
00135 ret = _nss_winbind_getpwnam_r (NSS_ARGS(args)->key.name,
00136 result,
00137 NSS_ARGS(args)->buf.buffer,
00138 NSS_ARGS(args)->buf.buflen,
00139 &NSS_ARGS(args)->erange);
00140 if(ret == NSS_STATUS_SUCCESS)
00141 NSS_ARGS(args)->returnval = (void*) result;
00142
00143 return ret;
00144 }
00145
00146 static NSS_STATUS
00147 _nss_winbind_getpwuid_solwrap(nss_backend_t* be, void* args)
00148 {
00149 NSS_STATUS ret;
00150 struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
00151
00152 NSS_DEBUG("_nss_winbind_getpwuid_solwrap");
00153 ret = _nss_winbind_getpwuid_r (NSS_ARGS(args)->key.uid,
00154 result,
00155 NSS_ARGS(args)->buf.buffer,
00156 NSS_ARGS(args)->buf.buflen,
00157 &NSS_ARGS(args)->erange);
00158 if(ret == NSS_STATUS_SUCCESS)
00159 NSS_ARGS(args)->returnval = (void*) result;
00160
00161 return ret;
00162 }
00163
00164 static NSS_STATUS _nss_winbind_passwd_destr (nss_backend_t * be, void *args)
00165 {
00166 SAFE_FREE(be);
00167 NSS_DEBUG("_nss_winbind_passwd_destr");
00168 return NSS_STATUS_SUCCESS;
00169 }
00170
00171 static nss_backend_op_t passwd_ops[] =
00172 {
00173 _nss_winbind_passwd_destr,
00174 _nss_winbind_endpwent_solwrap,
00175 _nss_winbind_setpwent_solwrap,
00176 _nss_winbind_getpwent_solwrap,
00177 _nss_winbind_getpwnam_solwrap,
00178 _nss_winbind_getpwuid_solwrap
00179 };
00180
00181 nss_backend_t*
00182 _nss_winbind_passwd_constr (const char* db_name,
00183 const char* src_name,
00184 const char* cfg_args)
00185 {
00186 nss_backend_t *be;
00187
00188 if(!(be = SMB_MALLOC_P(nss_backend_t)) )
00189 return NULL;
00190
00191 be->ops = passwd_ops;
00192 be->n_ops = sizeof(passwd_ops) / sizeof(nss_backend_op_t);
00193
00194 NSS_DEBUG("Initialized nss_winbind passwd backend");
00195 return be;
00196 }
00197
00198
00199
00200
00201
00202 static NSS_STATUS _nss_winbind_setgrent_solwrap (nss_backend_t* be, void* args)
00203 {
00204 NSS_DEBUG("_nss_winbind_setgrent_solwrap");
00205 return _nss_winbind_setgrent();
00206 }
00207
00208 static NSS_STATUS
00209 _nss_winbind_endgrent_solwrap (nss_backend_t * be, void *args)
00210 {
00211 NSS_DEBUG("_nss_winbind_endgrent_solwrap");
00212 return _nss_winbind_endgrent();
00213 }
00214
00215 static NSS_STATUS
00216 _nss_winbind_getgrent_solwrap(nss_backend_t* be, void* args)
00217 {
00218 NSS_STATUS ret;
00219 char* buffer = NSS_ARGS(args)->buf.buffer;
00220 int buflen = NSS_ARGS(args)->buf.buflen;
00221 struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
00222 int* errnop = &NSS_ARGS(args)->erange;
00223 char logmsg[80];
00224
00225 ret = _nss_winbind_getgrent_r(result, buffer,
00226 buflen, errnop);
00227
00228 if(ret == NSS_STATUS_SUCCESS)
00229 {
00230 snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning group: %s\n", result->gr_name);
00231 NSS_DEBUG(logmsg);
00232 NSS_ARGS(args)->returnval = (void*) result;
00233 } else {
00234 snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning error: %d.\n", ret);
00235 NSS_DEBUG(logmsg);
00236 }
00237
00238 return ret;
00239
00240 }
00241
00242 static NSS_STATUS
00243 _nss_winbind_getgrnam_solwrap(nss_backend_t* be, void* args)
00244 {
00245 NSS_STATUS ret;
00246 struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
00247
00248 NSS_DEBUG("_nss_winbind_getgrnam_solwrap");
00249 ret = _nss_winbind_getgrnam_r(NSS_ARGS(args)->key.name,
00250 result,
00251 NSS_ARGS(args)->buf.buffer,
00252 NSS_ARGS(args)->buf.buflen,
00253 &NSS_ARGS(args)->erange);
00254
00255 if(ret == NSS_STATUS_SUCCESS)
00256 NSS_ARGS(args)->returnval = (void*) result;
00257
00258 return ret;
00259 }
00260
00261 static NSS_STATUS
00262 _nss_winbind_getgrgid_solwrap(nss_backend_t* be, void* args)
00263 {
00264 NSS_STATUS ret;
00265 struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
00266
00267 NSS_DEBUG("_nss_winbind_getgrgid_solwrap");
00268 ret = _nss_winbind_getgrgid_r (NSS_ARGS(args)->key.gid,
00269 result,
00270 NSS_ARGS(args)->buf.buffer,
00271 NSS_ARGS(args)->buf.buflen,
00272 &NSS_ARGS(args)->erange);
00273
00274 if(ret == NSS_STATUS_SUCCESS)
00275 NSS_ARGS(args)->returnval = (void*) result;
00276
00277 return ret;
00278 }
00279
00280 static NSS_STATUS
00281 _nss_winbind_getgroupsbymember_solwrap(nss_backend_t* be, void* args)
00282 {
00283 int errnop;
00284 struct nss_groupsbymem *gmem = (struct nss_groupsbymem *)args;
00285
00286 NSS_DEBUG("_nss_winbind_getgroupsbymember");
00287
00288 _nss_winbind_initgroups_dyn(gmem->username,
00289 gmem->gid_array[0],
00290 &gmem->numgids,
00291 &gmem->maxgids,
00292 &gmem->gid_array,
00293 gmem->maxgids,
00294 &errnop);
00295
00296
00297
00298
00299
00300
00301
00302
00303 return (gmem->numgids == gmem->maxgids ? NSS_STATUS_SUCCESS : NSS_STATUS_NOTFOUND);
00304 }
00305
00306 static NSS_STATUS
00307 _nss_winbind_group_destr (nss_backend_t* be, void* args)
00308 {
00309 SAFE_FREE(be);
00310 NSS_DEBUG("_nss_winbind_group_destr");
00311 return NSS_STATUS_SUCCESS;
00312 }
00313
00314 static nss_backend_op_t group_ops[] =
00315 {
00316 _nss_winbind_group_destr,
00317 _nss_winbind_endgrent_solwrap,
00318 _nss_winbind_setgrent_solwrap,
00319 _nss_winbind_getgrent_solwrap,
00320 _nss_winbind_getgrnam_solwrap,
00321 _nss_winbind_getgrgid_solwrap,
00322 _nss_winbind_getgroupsbymember_solwrap
00323 };
00324
00325 nss_backend_t*
00326 _nss_winbind_group_constr (const char* db_name,
00327 const char* src_name,
00328 const char* cfg_args)
00329 {
00330 nss_backend_t* be;
00331
00332 if(!(be = SMB_MALLOC_P(nss_backend_t)) )
00333 return NULL;
00334
00335 be->ops = group_ops;
00336 be->n_ops = sizeof(group_ops) / sizeof(nss_backend_op_t);
00337
00338 NSS_DEBUG("Initialized nss_winbind group backend");
00339 return be;
00340 }
00341
00342
00343
00344
00345 #if defined(SUNOS5)
00346
00347
00348
00349
00350
00351 static NSS_STATUS
00352 parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response)
00353 {
00354 struct hostent *he = (struct hostent *)argp->buf.result;
00355 char *buffer = argp->buf.buffer;
00356 int buflen = argp->buf.buflen;
00357 NSS_STATUS ret;
00358
00359 char *p, *data;
00360 int addrcount = 0;
00361 int len = 0;
00362 struct in_addr *addrp;
00363 struct in6_addr *addrp6;
00364 int i;
00365
00366
00367
00368
00369
00370 p = strchr(response->data.winsresp, '\n');
00371 if(p) *p = '\0';
00372 else {
00373 argp->h_errno = NO_DATA;
00374 return NSS_STATUS_UNAVAIL;
00375 }
00376
00377 for(; p != response->data.winsresp; p--) {
00378 if(*p == '\t') addrcount++;
00379 }
00380
00381 if(addrcount == 0) {
00382 argp->h_errno = NO_DATA;
00383 return NSS_STATUS_UNAVAIL;
00384 }
00385
00386
00387 he->h_addrtype = af;
00388 if( he->h_addrtype == AF_INET) {
00389 he->h_length = sizeof(struct in_addr);
00390 addrp = (struct in_addr *)ROUND_DOWN(buffer + buflen,
00391 sizeof(struct in_addr));
00392 addrp -= addrcount;
00393 he->h_addr_list = (char **)ROUND_DOWN(addrp, sizeof (char*));
00394 he->h_addr_list -= addrcount+1;
00395 } else {
00396 he->h_length = sizeof(struct in6_addr);
00397 addrp6 = (struct in6_addr *)ROUND_DOWN(buffer + buflen,
00398 sizeof(struct in6_addr));
00399 addrp6 -= addrcount;
00400 he->h_addr_list = (char **)ROUND_DOWN(addrp6, sizeof (char*));
00401 he->h_addr_list -= addrcount+1;
00402 }
00403
00404
00405 if((char *)he->h_addr_list < buffer ) {
00406 argp->erange = 1;
00407 return NSS_STR_PARSE_ERANGE;
00408 }
00409
00410 data = response->data.winsresp;
00411 for( i = 0; i < addrcount; i++) {
00412 p = strchr(data, '\t');
00413 if(p == NULL) break;
00414
00415 *p = '\0';
00416 if(he->h_addrtype == AF_INET) {
00417 he->h_addr_list[i] = (char *)&addrp[i];
00418 if ((addrp[i].s_addr = inet_addr(data)) == -1) {
00419 argp->erange = 1;
00420 return NSS_STR_PARSE_ERANGE;
00421 }
00422 } else {
00423 he->h_addr_list[i] = (char *)&addrp6[i];
00424 if (strchr(data, ':') != 0) {
00425 if (inet_pton(AF_INET6, data, &addrp6[i]) != 1) {
00426 argp->erange = 1;
00427 return NSS_STR_PARSE_ERANGE;
00428 }
00429 } else {
00430 struct in_addr in4;
00431 if ((in4.s_addr = inet_addr(data)) == -1) {
00432 argp->erange = 1;
00433 return NSS_STR_PARSE_ERANGE;
00434 }
00435 IN6_INADDR_TO_V4MAPPED(&in4, &addrp6[i]);
00436 }
00437 }
00438 data = p+1;
00439 }
00440
00441 he->h_addr_list[i] = (char *)NULL;
00442
00443 len = strlen(data);
00444 if(len > he->h_addr_list - (char**)argp->buf.buffer) {
00445 argp->erange = 1;
00446 return NSS_STR_PARSE_ERANGE;
00447 }
00448
00449
00450
00451 he->h_aliases = _nss_netdb_aliases(data, len, buffer,
00452 ((char*) he->h_addr_list) - buffer);
00453 if(he->h_aliases == NULL) {
00454 argp->erange = 1;
00455 ret = NSS_STR_PARSE_ERANGE;
00456 } else {
00457 he->h_name = he->h_aliases[0];
00458 he->h_aliases++;
00459 ret = NSS_STR_PARSE_SUCCESS;
00460 }
00461
00462 argp->returnval = (void*)he;
00463 return ret;
00464 }
00465
00466 static NSS_STATUS
00467 _nss_winbind_ipnodes_getbyname(nss_backend_t* be, void *args)
00468 {
00469 nss_XbyY_args_t *argp = (nss_XbyY_args_t*) args;
00470 struct winbindd_response response;
00471 struct winbindd_request request;
00472 NSS_STATUS ret;
00473 int af;
00474
00475 ZERO_STRUCT(response);
00476 ZERO_STRUCT(request);
00477
00478
00479
00480
00481
00482
00483
00484
00485 #ifdef HAVE_NSS_XBYY_KEY_IPNODE
00486 af = argp->key.ipnode.af_family;
00487 if(af == AF_INET6 && argp->key.ipnode.flags == 0) {
00488 argp->h_errno = NO_DATA;
00489 return NSS_STATUS_UNAVAIL;
00490 }
00491 #else
00492
00493 af = AF_INET6;
00494 #endif
00495
00496 strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1);
00497 request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0';
00498
00499 if( (ret = winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response))
00500 == NSS_STATUS_SUCCESS ) {
00501 ret = parse_response(af, argp, &response);
00502 }
00503
00504 free_response(&response);
00505 return ret;
00506 }
00507
00508 static NSS_STATUS
00509 _nss_winbind_hosts_getbyname(nss_backend_t* be, void *args)
00510 {
00511 nss_XbyY_args_t *argp = (nss_XbyY_args_t*) args;
00512 struct winbindd_response response;
00513 struct winbindd_request request;
00514 NSS_STATUS ret;
00515
00516 ZERO_STRUCT(response);
00517 ZERO_STRUCT(request);
00518
00519 strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1);
00520 request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0';
00521
00522 if( (ret = winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response))
00523 == NSS_STATUS_SUCCESS ) {
00524 ret = parse_response(AF_INET, argp, &response);
00525 }
00526
00527 free_response(&response);
00528 return ret;
00529 }
00530
00531 static NSS_STATUS
00532 _nss_winbind_hosts_getbyaddr(nss_backend_t* be, void *args)
00533 {
00534 NSS_STATUS ret;
00535 struct winbindd_response response;
00536 struct winbindd_request request;
00537 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)args;
00538 const char *p;
00539
00540 ZERO_STRUCT(response);
00541 ZERO_STRUCT(request);
00542
00543
00544 if(argp->key.hostaddr.type == AF_INET6) {
00545 argp->h_errno = NO_DATA;
00546 return NSS_STATUS_UNAVAIL;
00547 }
00548
00549 p = inet_ntop(argp->key.hostaddr.type, argp->key.hostaddr.addr,
00550 request.data.winsreq, INET6_ADDRSTRLEN);
00551
00552 ret = winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response);
00553
00554 if( ret == NSS_STATUS_SUCCESS) {
00555 parse_response(argp->key.hostaddr.type, argp, &response);
00556 }
00557 free_response(&response);
00558 return ret;
00559 }
00560
00561
00562 static NSS_STATUS
00563 _nss_winbind_common_endent(nss_backend_t* be, void *args)
00564 {
00565 return (NSS_STATUS_UNAVAIL);
00566 }
00567
00568 static NSS_STATUS
00569 _nss_winbind_common_setent(nss_backend_t* be, void *args)
00570 {
00571 return (NSS_STATUS_UNAVAIL);
00572 }
00573
00574 static NSS_STATUS
00575 _nss_winbind_common_getent(nss_backend_t* be, void *args)
00576 {
00577 return (NSS_STATUS_UNAVAIL);
00578 }
00579
00580 static nss_backend_t*
00581 _nss_winbind_common_constr (nss_backend_op_t ops[], int n_ops)
00582 {
00583 nss_backend_t* be;
00584
00585 if(!(be = SMB_MALLOC_P(nss_backend_t)) )
00586 return NULL;
00587
00588 be->ops = ops;
00589 be->n_ops = n_ops;
00590
00591 return be;
00592 }
00593
00594 static NSS_STATUS
00595 _nss_winbind_common_destr (nss_backend_t* be, void* args)
00596 {
00597 SAFE_FREE(be);
00598 return NSS_STATUS_SUCCESS;
00599 }
00600
00601 static nss_backend_op_t ipnodes_ops[] = {
00602 _nss_winbind_common_destr,
00603 _nss_winbind_common_endent,
00604 _nss_winbind_common_setent,
00605 _nss_winbind_common_getent,
00606 _nss_winbind_ipnodes_getbyname,
00607 _nss_winbind_hosts_getbyaddr,
00608 };
00609
00610 nss_backend_t *
00611 _nss_winbind_ipnodes_constr(dummy1, dummy2, dummy3)
00612 const char *dummy1, *dummy2, *dummy3;
00613 {
00614 return (_nss_winbind_common_constr(ipnodes_ops,
00615 sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0])));
00616 }
00617
00618 static nss_backend_op_t host_ops[] = {
00619 _nss_winbind_common_destr,
00620 _nss_winbind_common_endent,
00621 _nss_winbind_common_setent,
00622 _nss_winbind_common_getent,
00623 _nss_winbind_hosts_getbyname,
00624 _nss_winbind_hosts_getbyaddr,
00625 };
00626
00627 nss_backend_t *
00628 _nss_winbind_hosts_constr(dummy1, dummy2, dummy3)
00629 const char *dummy1, *dummy2, *dummy3;
00630 {
00631 return (_nss_winbind_common_constr(host_ops,
00632 sizeof (host_ops) / sizeof (host_ops[0])));
00633 }
00634
00635 #endif
00636 #endif