00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "winbind_client.h"
00025
00026
00027
00028
00029
00030 #define MAX_GETPWENT_USERS 250
00031 #define MAX_GETGRENT_USERS 250
00032
00033 NSS_STATUS _nss_winbind_setpwent(void);
00034 NSS_STATUS _nss_winbind_endpwent(void);
00035 NSS_STATUS _nss_winbind_getpwent_r(struct passwd *result, char *buffer,
00036 size_t buflen, int *errnop);
00037 NSS_STATUS _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result,
00038 char *buffer, size_t buflen, int *errnop);
00039 NSS_STATUS _nss_winbind_getpwnam_r(const char *name, struct passwd *result,
00040 char *buffer, size_t buflen, int *errnop);
00041 NSS_STATUS _nss_winbind_setgrent(void);
00042 NSS_STATUS _nss_winbind_endgrent(void);
00043 NSS_STATUS _nss_winbind_getgrent_r(struct group *result, char *buffer,
00044 size_t buflen, int *errnop);
00045 NSS_STATUS _nss_winbind_getgrlst_r(struct group *result, char *buffer,
00046 size_t buflen, int *errnop);
00047 NSS_STATUS _nss_winbind_getgrnam_r(const char *name, struct group *result,
00048 char *buffer, size_t buflen, int *errnop);
00049 NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid, struct group *result, char *buffer,
00050 size_t buflen, int *errnop);
00051 NSS_STATUS _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
00052 long int *size, gid_t **groups,
00053 long int limit, int *errnop);
00054 NSS_STATUS _nss_winbind_getusersids(const char *user_sid, char **group_sids,
00055 int *num_groups, char *buffer, size_t buf_size,
00056 int *errnop);
00057 NSS_STATUS _nss_winbind_nametosid(const char *name, char **sid, char *buffer,
00058 size_t buflen, int *errnop);
00059 NSS_STATUS _nss_winbind_sidtoname(const char *sid, char **name, char *buffer,
00060 size_t buflen, int *errnop);
00061 NSS_STATUS _nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop);
00062 NSS_STATUS _nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop);
00063 NSS_STATUS _nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer,
00064 size_t buflen, int *errnop);
00065 NSS_STATUS _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer,
00066 size_t buflen, int *errnop);
00067
00068
00069
00070 extern int winbindd_fd;
00071
00072 #ifdef DEBUG_NSS
00073 static const char *nss_err_str(NSS_STATUS ret) {
00074 switch (ret) {
00075 case NSS_STATUS_TRYAGAIN:
00076 return "NSS_STATUS_TRYAGAIN";
00077 case NSS_STATUS_SUCCESS:
00078 return "NSS_STATUS_SUCCESS";
00079 case NSS_STATUS_NOTFOUND:
00080 return "NSS_STATUS_NOTFOUND";
00081 case NSS_STATUS_UNAVAIL:
00082 return "NSS_STATUS_UNAVAIL";
00083 case NSS_STATUS_RETURN:
00084 return "NSS_STATUS_RETURN";
00085 default:
00086 return "UNKNOWN RETURN CODE!!!!!!!";
00087 }
00088 }
00089 #endif
00090
00091
00092
00093
00094
00095 static char *get_static(char **buffer, size_t *buflen, size_t len)
00096 {
00097 char *result;
00098
00099
00100
00101
00102 if ((buffer == NULL) || (buflen == NULL) || (*buflen < len)) {
00103 return NULL;
00104 }
00105
00106
00107
00108 result = *buffer;
00109 *buffer += len;
00110 *buflen -= len;
00111
00112 return result;
00113 }
00114
00115
00116
00117
00118
00119 static BOOL next_token(char **ptr,char *buff,const char *sep, size_t bufsize)
00120 {
00121 char *s;
00122 BOOL quoted;
00123 size_t len=1;
00124
00125 if (!ptr) return(False);
00126
00127 s = *ptr;
00128
00129
00130 if (!sep) sep = " \t\n\r";
00131
00132
00133 while (*s && strchr(sep,*s)) s++;
00134
00135
00136 if (! *s) return(False);
00137
00138
00139 for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) {
00140 if (*s == '\"') {
00141 quoted = !quoted;
00142 } else {
00143 len++;
00144 *buff++ = *s;
00145 }
00146 }
00147
00148 *ptr = (*s) ? s+1 : s;
00149 *buff = 0;
00150
00151 return(True);
00152 }
00153
00154
00155
00156
00157
00158
00159 static NSS_STATUS fill_pwent(struct passwd *result,
00160 struct winbindd_pw *pw,
00161 char **buffer, size_t *buflen)
00162 {
00163
00164
00165 if ((result->pw_name =
00166 get_static(buffer, buflen, strlen(pw->pw_name) + 1)) == NULL) {
00167
00168
00169
00170 return NSS_STATUS_TRYAGAIN;
00171 }
00172
00173 strcpy(result->pw_name, pw->pw_name);
00174
00175
00176
00177 if ((result->pw_passwd =
00178 get_static(buffer, buflen, strlen(pw->pw_passwd) + 1)) == NULL) {
00179
00180
00181
00182 return NSS_STATUS_TRYAGAIN;
00183 }
00184
00185 strcpy(result->pw_passwd, pw->pw_passwd);
00186
00187
00188
00189 result->pw_uid = pw->pw_uid;
00190 result->pw_gid = pw->pw_gid;
00191
00192
00193
00194 if ((result->pw_gecos =
00195 get_static(buffer, buflen, strlen(pw->pw_gecos) + 1)) == NULL) {
00196
00197
00198
00199 return NSS_STATUS_TRYAGAIN;
00200 }
00201
00202 strcpy(result->pw_gecos, pw->pw_gecos);
00203
00204
00205
00206 if ((result->pw_dir =
00207 get_static(buffer, buflen, strlen(pw->pw_dir) + 1)) == NULL) {
00208
00209
00210
00211 return NSS_STATUS_TRYAGAIN;
00212 }
00213
00214 strcpy(result->pw_dir, pw->pw_dir);
00215
00216
00217
00218 if ((result->pw_shell =
00219 get_static(buffer, buflen, strlen(pw->pw_shell) + 1)) == NULL) {
00220
00221
00222
00223 return NSS_STATUS_TRYAGAIN;
00224 }
00225
00226 strcpy(result->pw_shell, pw->pw_shell);
00227
00228
00229
00230
00231 #if HAVE_PASSWD_PW_COMMENT
00232 result->pw_comment = "";
00233 #endif
00234
00235 #if HAVE_PASSWD_PW_AGE
00236 result->pw_age = "";
00237 #endif
00238
00239 return NSS_STATUS_SUCCESS;
00240 }
00241
00242
00243
00244
00245
00246 static NSS_STATUS fill_grent(struct group *result, struct winbindd_gr *gr,
00247 char *gr_mem, char **buffer, size_t *buflen)
00248 {
00249 fstring name;
00250 int i;
00251 char *tst;
00252
00253
00254
00255 if ((result->gr_name =
00256 get_static(buffer, buflen, strlen(gr->gr_name) + 1)) == NULL) {
00257
00258
00259
00260 return NSS_STATUS_TRYAGAIN;
00261 }
00262
00263 strcpy(result->gr_name, gr->gr_name);
00264
00265
00266
00267 if ((result->gr_passwd =
00268 get_static(buffer, buflen, strlen(gr->gr_passwd) + 1)) == NULL) {
00269
00270
00271
00272 return NSS_STATUS_TRYAGAIN;
00273 }
00274
00275 strcpy(result->gr_passwd, gr->gr_passwd);
00276
00277
00278
00279 result->gr_gid = gr->gr_gid;
00280
00281
00282
00283 if ((gr->num_gr_mem < 0) || !gr_mem) {
00284 gr->num_gr_mem = 0;
00285 }
00286
00287
00288
00289
00290 if ((i = (unsigned long)(*buffer) % sizeof(char*)) != 0)
00291 i = sizeof(char*) - i;
00292
00293 if ((tst = get_static(buffer, buflen, ((gr->num_gr_mem + 1) *
00294 sizeof(char *)+i))) == NULL) {
00295
00296
00297
00298 return NSS_STATUS_TRYAGAIN;
00299 }
00300 result->gr_mem = (char **)(tst + i);
00301
00302 if (gr->num_gr_mem == 0) {
00303
00304
00305
00306 *(result->gr_mem) = NULL;
00307 return NSS_STATUS_SUCCESS;
00308 }
00309
00310
00311
00312 i = 0;
00313
00314 while(next_token((char **)&gr_mem, name, ",", sizeof(fstring))) {
00315
00316
00317
00318 if (((result->gr_mem)[i] =
00319 get_static(buffer, buflen, strlen(name) + 1)) == NULL) {
00320
00321
00322
00323 return NSS_STATUS_TRYAGAIN;
00324 }
00325
00326 strcpy((result->gr_mem)[i], name);
00327 i++;
00328 }
00329
00330
00331
00332 (result->gr_mem)[i] = NULL;
00333
00334 return NSS_STATUS_SUCCESS;
00335 }
00336
00337
00338
00339
00340
00341 static struct winbindd_response getpwent_response;
00342
00343 static int ndx_pw_cache;
00344 static int num_pw_cache;
00345
00346
00347
00348 NSS_STATUS
00349 _nss_winbind_setpwent(void)
00350 {
00351 NSS_STATUS ret;
00352 #ifdef DEBUG_NSS
00353 fprintf(stderr, "[%5d]: setpwent\n", getpid());
00354 #endif
00355
00356 if (num_pw_cache > 0) {
00357 ndx_pw_cache = num_pw_cache = 0;
00358 free_response(&getpwent_response);
00359 }
00360
00361 ret = winbindd_request_response(WINBINDD_SETPWENT, NULL, NULL);
00362 #ifdef DEBUG_NSS
00363 fprintf(stderr, "[%5d]: setpwent returns %s (%d)\n", getpid(),
00364 nss_err_str(ret), ret);
00365 #endif
00366 return ret;
00367 }
00368
00369
00370
00371 NSS_STATUS
00372 _nss_winbind_endpwent(void)
00373 {
00374 NSS_STATUS ret;
00375 #ifdef DEBUG_NSS
00376 fprintf(stderr, "[%5d]: endpwent\n", getpid());
00377 #endif
00378
00379 if (num_pw_cache > 0) {
00380 ndx_pw_cache = num_pw_cache = 0;
00381 free_response(&getpwent_response);
00382 }
00383
00384 ret = winbindd_request_response(WINBINDD_ENDPWENT, NULL, NULL);
00385 #ifdef DEBUG_NSS
00386 fprintf(stderr, "[%5d]: endpwent returns %s (%d)\n", getpid(),
00387 nss_err_str(ret), ret);
00388 #endif
00389 return ret;
00390 }
00391
00392
00393
00394 NSS_STATUS
00395 _nss_winbind_getpwent_r(struct passwd *result, char *buffer,
00396 size_t buflen, int *errnop)
00397 {
00398 NSS_STATUS ret;
00399 struct winbindd_request request;
00400 static int called_again;
00401
00402 #ifdef DEBUG_NSS
00403 fprintf(stderr, "[%5d]: getpwent\n", getpid());
00404 #endif
00405
00406
00407
00408
00409 if ((ndx_pw_cache < num_pw_cache) || called_again) {
00410 goto return_result;
00411 }
00412
00413
00414
00415 if (num_pw_cache > 0) {
00416 free_response(&getpwent_response);
00417 }
00418
00419 ZERO_STRUCT(request);
00420 ZERO_STRUCT(getpwent_response);
00421
00422 request.data.num_entries = MAX_GETPWENT_USERS;
00423
00424 ret = winbindd_request_response(WINBINDD_GETPWENT, &request,
00425 &getpwent_response);
00426
00427 if (ret == NSS_STATUS_SUCCESS) {
00428 struct winbindd_pw *pw_cache;
00429
00430
00431
00432 ndx_pw_cache = 0;
00433 num_pw_cache = getpwent_response.data.num_entries;
00434
00435
00436
00437 return_result:
00438
00439 pw_cache = (struct winbindd_pw *)
00440 getpwent_response.extra_data.data;
00441
00442
00443
00444 if (pw_cache == NULL) {
00445 ret = NSS_STATUS_NOTFOUND;
00446 goto done;
00447 }
00448
00449 ret = fill_pwent(result, &pw_cache[ndx_pw_cache],
00450 &buffer, &buflen);
00451
00452
00453
00454 if (ret == NSS_STATUS_TRYAGAIN) {
00455 called_again = True;
00456 *errnop = errno = ERANGE;
00457 goto done;
00458 }
00459
00460 *errnop = errno = 0;
00461 called_again = False;
00462 ndx_pw_cache++;
00463
00464
00465
00466 if (ndx_pw_cache == num_pw_cache) {
00467 ndx_pw_cache = num_pw_cache = 0;
00468 free_response(&getpwent_response);
00469 }
00470 }
00471 done:
00472 #ifdef DEBUG_NSS
00473 fprintf(stderr, "[%5d]: getpwent returns %s (%d)\n", getpid(),
00474 nss_err_str(ret), ret);
00475 #endif
00476 return ret;
00477 }
00478
00479
00480
00481 NSS_STATUS
00482 _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer,
00483 size_t buflen, int *errnop)
00484 {
00485 NSS_STATUS ret;
00486 static struct winbindd_response response;
00487 struct winbindd_request request;
00488 static int keep_response=0;
00489
00490 #ifdef DEBUG_NSS
00491 fprintf(stderr, "[%5d]: getpwuid %d\n", getpid(), (unsigned int)uid);
00492 #endif
00493
00494
00495 if (!keep_response) {
00496
00497
00498
00499 ZERO_STRUCT(response);
00500 ZERO_STRUCT(request);
00501
00502 request.data.uid = uid;
00503
00504 ret = winbindd_request_response(WINBINDD_GETPWUID, &request, &response);
00505
00506 if (ret == NSS_STATUS_SUCCESS) {
00507 ret = fill_pwent(result, &response.data.pw,
00508 &buffer, &buflen);
00509
00510 if (ret == NSS_STATUS_TRYAGAIN) {
00511 keep_response = True;
00512 *errnop = errno = ERANGE;
00513 goto done;
00514 }
00515 }
00516
00517 } else {
00518
00519
00520
00521 ret = fill_pwent(result, &response.data.pw, &buffer, &buflen);
00522
00523 if (ret == NSS_STATUS_TRYAGAIN) {
00524 keep_response = True;
00525 *errnop = errno = ERANGE;
00526 goto done;
00527 }
00528
00529 keep_response = False;
00530 *errnop = errno = 0;
00531 }
00532
00533 free_response(&response);
00534 done:
00535
00536 #ifdef DEBUG_NSS
00537 fprintf(stderr, "[%5d]: getpwuid %d returns %s (%d)\n", getpid(),
00538 (unsigned int)uid, nss_err_str(ret), ret);
00539 #endif
00540 return ret;
00541 }
00542
00543
00544 NSS_STATUS
00545 _nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer,
00546 size_t buflen, int *errnop)
00547 {
00548 NSS_STATUS ret;
00549 static struct winbindd_response response;
00550 struct winbindd_request request;
00551 static int keep_response;
00552
00553 #ifdef DEBUG_NSS
00554 fprintf(stderr, "[%5d]: getpwnam %s\n", getpid(), name);
00555 #endif
00556
00557
00558
00559 if (!keep_response) {
00560
00561
00562
00563 ZERO_STRUCT(response);
00564 ZERO_STRUCT(request);
00565
00566 strncpy(request.data.username, name,
00567 sizeof(request.data.username) - 1);
00568 request.data.username
00569 [sizeof(request.data.username) - 1] = '\0';
00570
00571 ret = winbindd_request_response(WINBINDD_GETPWNAM, &request, &response);
00572
00573 if (ret == NSS_STATUS_SUCCESS) {
00574 ret = fill_pwent(result, &response.data.pw, &buffer,
00575 &buflen);
00576
00577 if (ret == NSS_STATUS_TRYAGAIN) {
00578 keep_response = True;
00579 *errnop = errno = ERANGE;
00580 goto done;
00581 }
00582 }
00583
00584 } else {
00585
00586
00587
00588 ret = fill_pwent(result, &response.data.pw, &buffer, &buflen);
00589
00590 if (ret == NSS_STATUS_TRYAGAIN) {
00591 keep_response = True;
00592 *errnop = errno = ERANGE;
00593 goto done;
00594 }
00595
00596 keep_response = False;
00597 *errnop = errno = 0;
00598 }
00599
00600 free_response(&response);
00601 done:
00602 #ifdef DEBUG_NSS
00603 fprintf(stderr, "[%5d]: getpwnam %s returns %s (%d)\n", getpid(),
00604 name, nss_err_str(ret), ret);
00605 #endif
00606 return ret;
00607 }
00608
00609
00610
00611
00612
00613 static struct winbindd_response getgrent_response;
00614
00615 static int ndx_gr_cache;
00616 static int num_gr_cache;
00617
00618
00619
00620 NSS_STATUS
00621 _nss_winbind_setgrent(void)
00622 {
00623 NSS_STATUS ret;
00624 #ifdef DEBUG_NSS
00625 fprintf(stderr, "[%5d]: setgrent\n", getpid());
00626 #endif
00627
00628 if (num_gr_cache > 0) {
00629 ndx_gr_cache = num_gr_cache = 0;
00630 free_response(&getgrent_response);
00631 }
00632
00633 ret = winbindd_request_response(WINBINDD_SETGRENT, NULL, NULL);
00634 #ifdef DEBUG_NSS
00635 fprintf(stderr, "[%5d]: setgrent returns %s (%d)\n", getpid(),
00636 nss_err_str(ret), ret);
00637 #endif
00638 return ret;
00639 }
00640
00641
00642
00643 NSS_STATUS
00644 _nss_winbind_endgrent(void)
00645 {
00646 NSS_STATUS ret;
00647 #ifdef DEBUG_NSS
00648 fprintf(stderr, "[%5d]: endgrent\n", getpid());
00649 #endif
00650
00651 if (num_gr_cache > 0) {
00652 ndx_gr_cache = num_gr_cache = 0;
00653 free_response(&getgrent_response);
00654 }
00655
00656 ret = winbindd_request_response(WINBINDD_ENDGRENT, NULL, NULL);
00657 #ifdef DEBUG_NSS
00658 fprintf(stderr, "[%5d]: endgrent returns %s (%d)\n", getpid(),
00659 nss_err_str(ret), ret);
00660 #endif
00661 return ret;
00662 }
00663
00664
00665
00666 static NSS_STATUS
00667 winbind_getgrent(enum winbindd_cmd cmd,
00668 struct group *result,
00669 char *buffer, size_t buflen, int *errnop)
00670 {
00671 NSS_STATUS ret;
00672 static struct winbindd_request request;
00673 static int called_again;
00674
00675
00676 #ifdef DEBUG_NSS
00677 fprintf(stderr, "[%5d]: getgrent\n", getpid());
00678 #endif
00679
00680
00681
00682
00683 if ((ndx_gr_cache < num_gr_cache) || called_again) {
00684 goto return_result;
00685 }
00686
00687
00688
00689 if (num_gr_cache > 0) {
00690 free_response(&getgrent_response);
00691 }
00692
00693 ZERO_STRUCT(request);
00694 ZERO_STRUCT(getgrent_response);
00695
00696 request.data.num_entries = MAX_GETGRENT_USERS;
00697
00698 ret = winbindd_request_response(cmd, &request,
00699 &getgrent_response);
00700
00701 if (ret == NSS_STATUS_SUCCESS) {
00702 struct winbindd_gr *gr_cache;
00703 int mem_ofs;
00704
00705
00706
00707 ndx_gr_cache = 0;
00708 num_gr_cache = getgrent_response.data.num_entries;
00709
00710
00711
00712 return_result:
00713
00714 gr_cache = (struct winbindd_gr *)
00715 getgrent_response.extra_data.data;
00716
00717
00718
00719 if (gr_cache == NULL) {
00720 ret = NSS_STATUS_NOTFOUND;
00721 goto done;
00722 }
00723
00724
00725
00726
00727
00728 mem_ofs = gr_cache[ndx_gr_cache].gr_mem_ofs +
00729 num_gr_cache * sizeof(struct winbindd_gr);
00730
00731 ret = fill_grent(result, &gr_cache[ndx_gr_cache],
00732 ((char *)getgrent_response.extra_data.data)+mem_ofs,
00733 &buffer, &buflen);
00734
00735
00736
00737 if (ret == NSS_STATUS_TRYAGAIN) {
00738 called_again = True;
00739 *errnop = errno = ERANGE;
00740 goto done;
00741 }
00742
00743 *errnop = 0;
00744 called_again = False;
00745 ndx_gr_cache++;
00746
00747
00748
00749 if (ndx_gr_cache == num_gr_cache) {
00750 ndx_gr_cache = num_gr_cache = 0;
00751 free_response(&getgrent_response);
00752 }
00753 }
00754 done:
00755 #ifdef DEBUG_NSS
00756 fprintf(stderr, "[%5d]: getgrent returns %s (%d)\n", getpid(),
00757 nss_err_str(ret), ret);
00758 #endif
00759 return ret;
00760 }
00761
00762
00763 NSS_STATUS
00764 _nss_winbind_getgrent_r(struct group *result,
00765 char *buffer, size_t buflen, int *errnop)
00766 {
00767 return winbind_getgrent(WINBINDD_GETGRENT, result, buffer, buflen, errnop);
00768 }
00769
00770 NSS_STATUS
00771 _nss_winbind_getgrlst_r(struct group *result,
00772 char *buffer, size_t buflen, int *errnop)
00773 {
00774 return winbind_getgrent(WINBINDD_GETGRLST, result, buffer, buflen, errnop);
00775 }
00776
00777
00778
00779 NSS_STATUS
00780 _nss_winbind_getgrnam_r(const char *name,
00781 struct group *result, char *buffer,
00782 size_t buflen, int *errnop)
00783 {
00784 NSS_STATUS ret;
00785 static struct winbindd_response response;
00786 struct winbindd_request request;
00787 static int keep_response;
00788
00789 #ifdef DEBUG_NSS
00790 fprintf(stderr, "[%5d]: getgrnam %s\n", getpid(), name);
00791 #endif
00792
00793
00794
00795 if (!keep_response) {
00796
00797
00798
00799 ZERO_STRUCT(request);
00800 ZERO_STRUCT(response);
00801
00802 strncpy(request.data.groupname, name,
00803 sizeof(request.data.groupname));
00804 request.data.groupname
00805 [sizeof(request.data.groupname) - 1] = '\0';
00806
00807 ret = winbindd_request_response(WINBINDD_GETGRNAM, &request, &response);
00808
00809 if (ret == NSS_STATUS_SUCCESS) {
00810 ret = fill_grent(result, &response.data.gr,
00811 (char *)response.extra_data.data,
00812 &buffer, &buflen);
00813
00814 if (ret == NSS_STATUS_TRYAGAIN) {
00815 keep_response = True;
00816 *errnop = errno = ERANGE;
00817 goto done;
00818 }
00819 }
00820
00821 } else {
00822
00823
00824
00825 ret = fill_grent(result, &response.data.gr,
00826 (char *)response.extra_data.data, &buffer,
00827 &buflen);
00828
00829 if (ret == NSS_STATUS_TRYAGAIN) {
00830 keep_response = True;
00831 *errnop = errno = ERANGE;
00832 goto done;
00833 }
00834
00835 keep_response = False;
00836 *errnop = 0;
00837 }
00838
00839 free_response(&response);
00840 done:
00841 #ifdef DEBUG_NSS
00842 fprintf(stderr, "[%5d]: getgrnam %s returns %s (%d)\n", getpid(),
00843 name, nss_err_str(ret), ret);
00844 #endif
00845 return ret;
00846 }
00847
00848
00849
00850 NSS_STATUS
00851 _nss_winbind_getgrgid_r(gid_t gid,
00852 struct group *result, char *buffer,
00853 size_t buflen, int *errnop)
00854 {
00855 NSS_STATUS ret;
00856 static struct winbindd_response response;
00857 struct winbindd_request request;
00858 static int keep_response;
00859
00860 #ifdef DEBUG_NSS
00861 fprintf(stderr, "[%5d]: getgrgid %d\n", getpid(), gid);
00862 #endif
00863
00864
00865
00866 if (!keep_response) {
00867
00868
00869
00870 ZERO_STRUCT(request);
00871 ZERO_STRUCT(response);
00872
00873 request.data.gid = gid;
00874
00875 ret = winbindd_request_response(WINBINDD_GETGRGID, &request, &response);
00876
00877 if (ret == NSS_STATUS_SUCCESS) {
00878
00879 ret = fill_grent(result, &response.data.gr,
00880 (char *)response.extra_data.data,
00881 &buffer, &buflen);
00882
00883 if (ret == NSS_STATUS_TRYAGAIN) {
00884 keep_response = True;
00885 *errnop = errno = ERANGE;
00886 goto done;
00887 }
00888 }
00889
00890 } else {
00891
00892
00893
00894 ret = fill_grent(result, &response.data.gr,
00895 (char *)response.extra_data.data, &buffer,
00896 &buflen);
00897
00898 if (ret == NSS_STATUS_TRYAGAIN) {
00899 keep_response = True;
00900 *errnop = errno = ERANGE;
00901 goto done;
00902 }
00903
00904 keep_response = False;
00905 *errnop = 0;
00906 }
00907
00908 free_response(&response);
00909 done:
00910 #ifdef DEBUG_NSS
00911 fprintf(stderr, "[%5d]: getgrgid %d returns %s (%d)\n", getpid(),
00912 (unsigned int)gid, nss_err_str(ret), ret);
00913 #endif
00914 return ret;
00915 }
00916
00917
00918
00919 NSS_STATUS
00920 _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
00921 long int *size, gid_t **groups, long int limit,
00922 int *errnop)
00923 {
00924 NSS_STATUS ret;
00925 struct winbindd_request request;
00926 struct winbindd_response response;
00927 int i;
00928
00929 #ifdef DEBUG_NSS
00930 fprintf(stderr, "[%5d]: initgroups %s (%d)\n", getpid(),
00931 user, group);
00932 #endif
00933
00934 ZERO_STRUCT(request);
00935 ZERO_STRUCT(response);
00936
00937 strncpy(request.data.username, user,
00938 sizeof(request.data.username) - 1);
00939
00940 ret = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
00941
00942 if (ret == NSS_STATUS_SUCCESS) {
00943 int num_gids = response.data.num_entries;
00944 gid_t *gid_list = (gid_t *)response.extra_data.data;
00945
00946 #ifdef DEBUG_NSS
00947 fprintf(stderr, "[%5d]: initgroups %s: got NSS_STATUS_SUCCESS "
00948 "and %d gids\n", getpid(),
00949 user, num_gids);
00950 #endif
00951 if (gid_list == NULL) {
00952 ret = NSS_STATUS_NOTFOUND;
00953 goto done;
00954 }
00955
00956
00957
00958 for (i = 0; i < num_gids; i++) {
00959
00960 #ifdef DEBUG_NSS
00961 fprintf(stderr, "[%5d]: initgroups %s (%d): "
00962 "processing gid %d \n", getpid(),
00963 user, group, gid_list[i]);
00964 #endif
00965
00966
00967
00968 if (gid_list[i] == group) {
00969 continue;
00970 }
00971
00972
00973
00974 if (*start == *size) {
00975 long int newsize;
00976 gid_t *newgroups;
00977
00978 newsize = 2 * (*size);
00979 if (limit > 0) {
00980 if (*size == limit) {
00981 goto done;
00982 }
00983 if (newsize > limit) {
00984 newsize = limit;
00985 }
00986 }
00987
00988 newgroups = (gid_t *)
00989 realloc((*groups),
00990 newsize * sizeof(**groups));
00991 if (!newgroups) {
00992 *errnop = ENOMEM;
00993 ret = NSS_STATUS_NOTFOUND;
00994 goto done;
00995 }
00996 *groups = newgroups;
00997 *size = newsize;
00998 }
00999
01000
01001
01002 (*groups)[*start] = gid_list[i];
01003 *start += 1;
01004 }
01005 }
01006
01007
01008
01009 done:
01010 #ifdef DEBUG_NSS
01011 fprintf(stderr, "[%5d]: initgroups %s returns %s (%d)\n", getpid(),
01012 user, nss_err_str(ret), ret);
01013 #endif
01014 return ret;
01015 }
01016
01017
01018
01019 NSS_STATUS
01020 _nss_winbind_getusersids(const char *user_sid, char **group_sids,
01021 int *num_groups,
01022 char *buffer, size_t buf_size, int *errnop)
01023 {
01024 NSS_STATUS ret;
01025 struct winbindd_request request;
01026 struct winbindd_response response;
01027
01028 #ifdef DEBUG_NSS
01029 fprintf(stderr, "[%5d]: getusersids %s\n", getpid(), user_sid);
01030 #endif
01031
01032 ZERO_STRUCT(request);
01033 ZERO_STRUCT(response);
01034
01035 strncpy(request.data.sid, user_sid,sizeof(request.data.sid) - 1);
01036 request.data.sid[sizeof(request.data.sid) - 1] = '\0';
01037
01038 ret = winbindd_request_response(WINBINDD_GETUSERSIDS, &request, &response);
01039
01040 if (ret != NSS_STATUS_SUCCESS) {
01041 goto done;
01042 }
01043
01044 if (buf_size < response.length - sizeof(response)) {
01045 ret = NSS_STATUS_TRYAGAIN;
01046 errno = *errnop = ERANGE;
01047 goto done;
01048 }
01049
01050 *num_groups = response.data.num_entries;
01051 *group_sids = buffer;
01052 memcpy(buffer, response.extra_data.data, response.length - sizeof(response));
01053 errno = *errnop = 0;
01054
01055 done:
01056 free_response(&response);
01057 return ret;
01058 }
01059
01060
01061
01062 NSS_STATUS
01063 _nss_winbind_nametosid(const char *name, char **sid, char *buffer,
01064 size_t buflen, int *errnop)
01065 {
01066 NSS_STATUS ret;
01067 struct winbindd_response response;
01068 struct winbindd_request request;
01069
01070 #ifdef DEBUG_NSS
01071 fprintf(stderr, "[%5d]: nametosid %s\n", getpid(), name);
01072 #endif
01073
01074 ZERO_STRUCT(response);
01075 ZERO_STRUCT(request);
01076
01077 strncpy(request.data.name.name, name,
01078 sizeof(request.data.name.name) - 1);
01079 request.data.name.name[sizeof(request.data.name.name) - 1] = '\0';
01080
01081 ret = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response);
01082 if (ret != NSS_STATUS_SUCCESS) {
01083 *errnop = errno = EINVAL;
01084 goto failed;
01085 }
01086
01087 if (buflen < strlen(response.data.sid.sid)+1) {
01088 ret = NSS_STATUS_TRYAGAIN;
01089 *errnop = errno = ERANGE;
01090 goto failed;
01091 }
01092
01093 *errnop = errno = 0;
01094 *sid = buffer;
01095 strcpy(*sid, response.data.sid.sid);
01096
01097 failed:
01098 free_response(&response);
01099 return ret;
01100 }
01101
01102
01103 NSS_STATUS
01104 _nss_winbind_sidtoname(const char *sid, char **name, char *buffer,
01105 size_t buflen, int *errnop)
01106 {
01107 NSS_STATUS ret;
01108 struct winbindd_response response;
01109 struct winbindd_request request;
01110 static char sep_char;
01111 unsigned needed;
01112
01113 #ifdef DEBUG_NSS
01114 fprintf(stderr, "[%5d]: sidtoname %s\n", getpid(), sid);
01115 #endif
01116
01117 ZERO_STRUCT(response);
01118 ZERO_STRUCT(request);
01119
01120
01121 if (!sep_char) {
01122 ret = winbindd_request_response(WINBINDD_INFO, &request, &response);
01123 if (ret != NSS_STATUS_SUCCESS) {
01124 *errnop = errno = EINVAL;
01125 goto failed;
01126 }
01127
01128 sep_char = response.data.info.winbind_separator;
01129 free_response(&response);
01130 }
01131
01132
01133 strncpy(request.data.sid, sid,
01134 sizeof(request.data.sid) - 1);
01135 request.data.sid[sizeof(request.data.sid) - 1] = '\0';
01136
01137 ret = winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response);
01138 if (ret != NSS_STATUS_SUCCESS) {
01139 *errnop = errno = EINVAL;
01140 goto failed;
01141 }
01142
01143 needed =
01144 strlen(response.data.name.dom_name) +
01145 strlen(response.data.name.name) + 2;
01146
01147 if (buflen < needed) {
01148 ret = NSS_STATUS_TRYAGAIN;
01149 *errnop = errno = ERANGE;
01150 goto failed;
01151 }
01152
01153 snprintf(buffer, needed, "%s%c%s",
01154 response.data.name.dom_name,
01155 sep_char,
01156 response.data.name.name);
01157
01158 *name = buffer;
01159 *errnop = errno = 0;
01160
01161 failed:
01162 free_response(&response);
01163 return ret;
01164 }
01165
01166
01167 NSS_STATUS
01168 _nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop)
01169 {
01170 NSS_STATUS ret;
01171 struct winbindd_response response;
01172 struct winbindd_request request;
01173
01174 #ifdef DEBUG_NSS
01175 fprintf(stderr, "[%5d]: sidtouid %s\n", getpid(), sid);
01176 #endif
01177
01178 ZERO_STRUCT(request);
01179 ZERO_STRUCT(response);
01180
01181 strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1);
01182 request.data.sid[sizeof(request.data.sid) - 1] = '\0';
01183
01184 ret = winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response);
01185 if (ret != NSS_STATUS_SUCCESS) {
01186 *errnop = errno = EINVAL;
01187 goto failed;
01188 }
01189
01190 *uid = response.data.uid;
01191
01192 failed:
01193 return ret;
01194 }
01195
01196
01197 NSS_STATUS
01198 _nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop)
01199 {
01200 NSS_STATUS ret;
01201 struct winbindd_response response;
01202 struct winbindd_request request;
01203
01204 #ifdef DEBUG_NSS
01205 fprintf(stderr, "[%5d]: sidtogid %s\n", getpid(), sid);
01206 #endif
01207
01208 ZERO_STRUCT(request);
01209 ZERO_STRUCT(response);
01210
01211 strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1);
01212 request.data.sid[sizeof(request.data.sid) - 1] = '\0';
01213
01214 ret = winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response);
01215 if (ret != NSS_STATUS_SUCCESS) {
01216 *errnop = errno = EINVAL;
01217 goto failed;
01218 }
01219
01220 *gid = response.data.gid;
01221
01222 failed:
01223 return ret;
01224 }
01225
01226
01227 NSS_STATUS
01228 _nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer,
01229 size_t buflen, int *errnop)
01230 {
01231 NSS_STATUS ret;
01232 struct winbindd_response response;
01233 struct winbindd_request request;
01234
01235 #ifdef DEBUG_NSS
01236 fprintf(stderr, "[%5u]: uidtosid %u\n", (unsigned int)getpid(), (unsigned int)uid);
01237 #endif
01238
01239 ZERO_STRUCT(response);
01240 ZERO_STRUCT(request);
01241
01242 request.data.uid = uid;
01243
01244 ret = winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response);
01245 if (ret != NSS_STATUS_SUCCESS) {
01246 *errnop = errno = EINVAL;
01247 goto failed;
01248 }
01249
01250 if (buflen < strlen(response.data.sid.sid)+1) {
01251 ret = NSS_STATUS_TRYAGAIN;
01252 *errnop = errno = ERANGE;
01253 goto failed;
01254 }
01255
01256 *errnop = errno = 0;
01257 *sid = buffer;
01258 strcpy(*sid, response.data.sid.sid);
01259
01260 failed:
01261 free_response(&response);
01262 return ret;
01263 }
01264
01265
01266 NSS_STATUS
01267 _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer,
01268 size_t buflen, int *errnop)
01269 {
01270 NSS_STATUS ret;
01271 struct winbindd_response response;
01272 struct winbindd_request request;
01273
01274 #ifdef DEBUG_NSS
01275 fprintf(stderr, "[%5u]: gidtosid %u\n", (unsigned int)getpid(), (unsigned int)gid);
01276 #endif
01277
01278 ZERO_STRUCT(response);
01279 ZERO_STRUCT(request);
01280
01281 request.data.gid = gid;
01282
01283 ret = winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response);
01284 if (ret != NSS_STATUS_SUCCESS) {
01285 *errnop = errno = EINVAL;
01286 goto failed;
01287 }
01288
01289 if (buflen < strlen(response.data.sid.sid)+1) {
01290 ret = NSS_STATUS_TRYAGAIN;
01291 *errnop = errno = ERANGE;
01292 goto failed;
01293 }
01294
01295 *errnop = errno = 0;
01296 *sid = buffer;
01297 strcpy(*sid, response.data.sid.sid);
01298
01299 failed:
01300 free_response(&response);
01301 return ret;
01302 }