関数 | |
BOOL | winbind_env_set (void) |
BOOL | winbind_off (void) |
BOOL | winbind_on (void) |
void | free_response (struct winbindd_response *response) |
void | init_request (struct winbindd_request *request, int request_type) |
static void | init_response (struct winbindd_response *response) |
void | close_sock (void) |
static int | make_nonstd_fd_internals (int fd, int limit) |
static int | make_safe_fd (int fd) |
static int | winbind_named_pipe_sock (const char *dir) |
static int | winbind_open_pipe_sock (int recursing, int need_priv) |
int | write_sock (void *buffer, int count, int recursing, int need_priv) |
static int | read_sock (void *buffer, int count) |
int | read_reply (struct winbindd_response *response) |
NSS_STATUS | winbindd_send_request (int req_type, int need_priv, struct winbindd_request *request) |
NSS_STATUS | winbindd_get_response (struct winbindd_response *response) |
NSS_STATUS | winbindd_request_response (int req_type, struct winbindd_request *request, struct winbindd_response *response) |
NSS_STATUS | winbindd_priv_request_response (int req_type, struct winbindd_request *request, struct winbindd_response *response) |
変数 | |
int | winbindd_fd = -1 |
static int | is_privileged = 0 |
BOOL winbind_env_set | ( | void | ) |
wb_common.c の 540 行で定義されています。
参照元 get_memberuids()・sys_getgrouplist()・winbindd_send_request().
00541 { 00542 char *env; 00543 00544 if ((env=getenv(WINBINDD_DONT_ENV)) != NULL) { 00545 if(strcmp(env, "1") == 0) { 00546 return True; 00547 } 00548 } 00549 return False; 00550 }
BOOL winbind_off | ( | void | ) |
wb_common.c の 678 行で定義されています。
参照元 get_memberuids()・idmap_nss_sids_to_unixids()・idmap_nss_unixids_to_sids()・main()・make_server_info_sam()・sys_getgrouplist().
00679 { 00680 static char *s = CONST_DISCARD(char *, WINBINDD_DONT_ENV "=1"); 00681 00682 return putenv(s) != -1; 00683 }
BOOL winbind_on | ( | void | ) |
wb_common.c の 685 行で定義されています。
参照元 get_memberuids()・idmap_nss_sids_to_unixids()・idmap_nss_unixids_to_sids()・sys_getgrouplist().
00686 { 00687 static char *s = CONST_DISCARD(char *, WINBINDD_DONT_ENV "=0"); 00688 00689 return putenv(s) != -1; 00690 }
void free_response | ( | struct winbindd_response * | response | ) |
wb_common.c の 40 行で定義されています。
参照先 winbindd_response::data・winbindd_response::extra_data.
参照元 _nss_winbind_endgrent()・_nss_winbind_endpwent()・_nss_winbind_getgrgid_r()・_nss_winbind_getgrnam_r()・_nss_winbind_getpwent_r()・_nss_winbind_getpwnam_r()・_nss_winbind_getpwuid_r()・_nss_winbind_getusersids()・_nss_winbind_gidtosid()・_nss_winbind_hosts_getbyaddr()・_nss_winbind_hosts_getbyname()・_nss_winbind_ipnodes_getbyname()・_nss_winbind_nametosid()・_nss_winbind_setgrent()・_nss_winbind_setpwent()・_nss_winbind_sidtoname()・_nss_winbind_uidtosid()・contact_winbind_auth_crap()・contact_winbind_change_pswd_auth_crap()・do_ccache_ntlm_auth()・read_reply()・wb_aix_authenticate()・wb_aix_chpass()・wb_aix_getgrgid()・wb_aix_getgrnam()・wb_aix_getgrset()・wb_aix_getpwnam()・wb_aix_getpwuid()・wb_aix_lsgroup()・wb_aix_lsuser()・winbind_callback()・winbind_getgrent()・winbindd_get_response().
00041 { 00042 /* Free any allocated extra_data */ 00043 00044 if (response) 00045 SAFE_FREE(response->extra_data.data); 00046 }
void init_request | ( | struct winbindd_request * | request, | |
int | request_type | |||
) |
wb_common.c の 50 行で定義されています。
参照先 winbindd_request::cmd・winbindd_request::length・winbindd_request::pid.
参照元 pam_winbind_request()・winbindd_send_request().
00051 { 00052 request->length = sizeof(struct winbindd_request); 00053 00054 request->cmd = (enum winbindd_cmd)request_type; 00055 request->pid = getpid(); 00056 00057 }
static void init_response | ( | struct winbindd_response * | response | ) | [static] |
wb_common.c の 61 行で定義されています。
参照先 winbindd_response::result・WINBINDD_ERROR.
00062 { 00063 /* Initialise return value */ 00064 00065 response->result = WINBINDD_ERROR; 00066 }
void close_sock | ( | void | ) |
wb_common.c の 70 行で定義されています。
参照先 winbindd_fd.
参照元 pam_winbind_request()・read_sock()・winbind_open_pipe_sock()・write_sock().
00071 { 00072 if (winbindd_fd != -1) { 00073 close(winbindd_fd); 00074 winbindd_fd = -1; 00075 } 00076 }
static int make_nonstd_fd_internals | ( | int | fd, | |
int | limit | |||
) | [static] |
wb_common.c の 83 行で定義されています。
参照元 make_safe_fd().
00084 { 00085 int new_fd; 00086 if (fd >= 0 && fd <= 2) { 00087 #ifdef F_DUPFD 00088 if ((new_fd = fcntl(fd, F_DUPFD, 3)) == -1) { 00089 return -1; 00090 } 00091 /* Paranoia */ 00092 if (new_fd < 3) { 00093 close(new_fd); 00094 return -1; 00095 } 00096 close(fd); 00097 return new_fd; 00098 #else 00099 if (limit <= 0) 00100 return -1; 00101 00102 new_fd = dup(fd); 00103 if (new_fd == -1) 00104 return -1; 00105 00106 /* use the program stack to hold our list of FDs to close */ 00107 new_fd = make_nonstd_fd_internals(new_fd, limit - 1); 00108 close(fd); 00109 return new_fd; 00110 #endif 00111 } 00112 return fd; 00113 }
static int make_safe_fd | ( | int | fd | ) | [static] |
wb_common.c の 123 行で定義されています。
参照先 flags・make_nonstd_fd_internals()・result.
参照元 winbind_named_pipe_sock().
00124 { 00125 int result, flags; 00126 int new_fd = make_nonstd_fd_internals(fd, RECURSION_LIMIT); 00127 if (new_fd == -1) { 00128 close(fd); 00129 return -1; 00130 } 00131 00132 /* Socket should be nonblocking. */ 00133 #ifdef O_NONBLOCK 00134 #define FLAG_TO_SET O_NONBLOCK 00135 #else 00136 #ifdef SYSV 00137 #define FLAG_TO_SET O_NDELAY 00138 #else /* BSD */ 00139 #define FLAG_TO_SET FNDELAY 00140 #endif 00141 #endif 00142 00143 if ((flags = fcntl(new_fd, F_GETFL)) == -1) { 00144 close(new_fd); 00145 return -1; 00146 } 00147 00148 flags |= FLAG_TO_SET; 00149 if (fcntl(new_fd, F_SETFL, flags) == -1) { 00150 close(new_fd); 00151 return -1; 00152 } 00153 00154 #undef FLAG_TO_SET 00155 00156 /* Socket should be closed on exec() */ 00157 #ifdef FD_CLOEXEC 00158 result = flags = fcntl(new_fd, F_GETFD, 0); 00159 if (flags >= 0) { 00160 flags |= FD_CLOEXEC; 00161 result = fcntl( new_fd, F_SETFD, flags ); 00162 } 00163 if (result < 0) { 00164 close(new_fd); 00165 return -1; 00166 } 00167 #endif 00168 return new_fd; 00169 }
static int winbind_named_pipe_sock | ( | const char * | dir | ) | [static] |
wb_common.c の 173 行で定義されています。
参照先 errno・fd・make_safe_fd().
00174 { 00175 struct sockaddr_un sunaddr; 00176 struct stat st; 00177 pstring path; 00178 int fd; 00179 int wait_time; 00180 int slept; 00181 00182 /* Check permissions on unix socket directory */ 00183 00184 if (lstat(dir, &st) == -1) { 00185 errno = ENOENT; 00186 return -1; 00187 } 00188 00189 if (!S_ISDIR(st.st_mode) || 00190 (st.st_uid != 0 && st.st_uid != geteuid())) { 00191 errno = ENOENT; 00192 return -1; 00193 } 00194 00195 /* Connect to socket */ 00196 00197 strncpy(path, dir, sizeof(path) - 1); 00198 path[sizeof(path) - 1] = '\0'; 00199 00200 strncat(path, "/", sizeof(path) - 1 - strlen(path)); 00201 path[sizeof(path) - 1] = '\0'; 00202 00203 strncat(path, WINBINDD_SOCKET_NAME, sizeof(path) - 1 - strlen(path)); 00204 path[sizeof(path) - 1] = '\0'; 00205 00206 ZERO_STRUCT(sunaddr); 00207 sunaddr.sun_family = AF_UNIX; 00208 strncpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path) - 1); 00209 00210 /* If socket file doesn't exist, don't bother trying to connect 00211 with retry. This is an attempt to make the system usable when 00212 the winbindd daemon is not running. */ 00213 00214 if (lstat(path, &st) == -1) { 00215 errno = ENOENT; 00216 return -1; 00217 } 00218 00219 /* Check permissions on unix socket file */ 00220 00221 if (!S_ISSOCK(st.st_mode) || 00222 (st.st_uid != 0 && st.st_uid != geteuid())) { 00223 errno = ENOENT; 00224 return -1; 00225 } 00226 00227 /* Connect to socket */ 00228 00229 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { 00230 return -1; 00231 } 00232 00233 /* Set socket non-blocking and close on exec. */ 00234 00235 if ((fd = make_safe_fd( fd)) == -1) { 00236 return fd; 00237 } 00238 00239 for (wait_time = 0; connect(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1; 00240 wait_time += slept) { 00241 struct timeval tv; 00242 fd_set w_fds; 00243 int ret; 00244 int connect_errno = 0; 00245 socklen_t errnosize; 00246 00247 if (wait_time >= CONNECT_TIMEOUT) 00248 goto error_out; 00249 00250 switch (errno) { 00251 case EINPROGRESS: 00252 FD_ZERO(&w_fds); 00253 FD_SET(fd, &w_fds); 00254 tv.tv_sec = CONNECT_TIMEOUT - wait_time; 00255 tv.tv_usec = 0; 00256 00257 ret = select(fd + 1, NULL, &w_fds, NULL, &tv); 00258 00259 if (ret > 0) { 00260 errnosize = sizeof(connect_errno); 00261 00262 ret = getsockopt(fd, SOL_SOCKET, 00263 SO_ERROR, &connect_errno, &errnosize); 00264 00265 if (ret >= 0 && connect_errno == 0) { 00266 /* Connect succeed */ 00267 goto out; 00268 } 00269 } 00270 00271 slept = CONNECT_TIMEOUT; 00272 break; 00273 case EAGAIN: 00274 slept = rand() % 3 + 1; 00275 sleep(slept); 00276 break; 00277 default: 00278 goto error_out; 00279 } 00280 00281 } 00282 00283 out: 00284 00285 return fd; 00286 00287 error_out: 00288 00289 close(fd); 00290 return -1; 00291 }
static int winbind_open_pipe_sock | ( | int | recursing, | |
int | need_priv | |||
) | [static] |
wb_common.c の 295 行で定義されています。
参照先 close_sock()・winbindd_response::data・winbindd_response::extra_data・fd・winbindd_request::flags・winbindd_response::interface_version・is_privileged・NSS_STATUS_SUCCESS・winbind_named_pipe_sock()・winbindd_fd・WINBINDD_INTERFACE_VERSION・WINBINDD_PRIV_PIPE_DIR・winbindd_request_response().
参照元 write_sock().
00296 { 00297 #ifdef HAVE_UNIXSOCKET 00298 static pid_t our_pid; 00299 struct winbindd_request request; 00300 struct winbindd_response response; 00301 ZERO_STRUCT(request); 00302 ZERO_STRUCT(response); 00303 00304 if (our_pid != getpid()) { 00305 close_sock(); 00306 our_pid = getpid(); 00307 } 00308 00309 if ((need_priv != 0) && (is_privileged == 0)) { 00310 close_sock(); 00311 } 00312 00313 if (winbindd_fd != -1) { 00314 return winbindd_fd; 00315 } 00316 00317 if (recursing) { 00318 return -1; 00319 } 00320 00321 if ((winbindd_fd = winbind_named_pipe_sock(WINBINDD_SOCKET_DIR)) == -1) { 00322 return -1; 00323 } 00324 00325 is_privileged = 0; 00326 00327 /* version-check the socket */ 00328 00329 request.flags = WBFLAG_RECURSE; 00330 if ((winbindd_request_response(WINBINDD_INTERFACE_VERSION, &request, &response) != NSS_STATUS_SUCCESS) || (response.data.interface_version != WINBIND_INTERFACE_VERSION)) { 00331 close_sock(); 00332 return -1; 00333 } 00334 00335 /* try and get priv pipe */ 00336 00337 request.flags = WBFLAG_RECURSE; 00338 if (winbindd_request_response(WINBINDD_PRIV_PIPE_DIR, &request, &response) == NSS_STATUS_SUCCESS) { 00339 int fd; 00340 if ((fd = winbind_named_pipe_sock((char *)response.extra_data.data)) != -1) { 00341 close(winbindd_fd); 00342 winbindd_fd = fd; 00343 is_privileged = 1; 00344 } 00345 } 00346 00347 if ((need_priv != 0) && (is_privileged == 0)) { 00348 return -1; 00349 } 00350 00351 SAFE_FREE(response.extra_data.data); 00352 00353 return winbindd_fd; 00354 #else 00355 return -1; 00356 #endif /* HAVE_UNIXSOCKET */ 00357 }
int write_sock | ( | void * | buffer, | |
int | count, | |||
int | recursing, | |||
int | need_priv | |||
) |
wb_common.c の 361 行で定義されています。
参照先 close_sock()・errno・result・winbind_open_pipe_sock()・winbindd_fd.
参照元 pam_winbind_request()・winbindd_send_request().
00362 { 00363 int result, nwritten; 00364 00365 /* Open connection to winbind daemon */ 00366 00367 restart: 00368 00369 if (winbind_open_pipe_sock(recursing, need_priv) == -1) { 00370 errno = ENOENT; 00371 return -1; 00372 } 00373 00374 /* Write data to socket */ 00375 00376 nwritten = 0; 00377 00378 while(nwritten < count) { 00379 struct timeval tv; 00380 fd_set r_fds; 00381 00382 /* Catch pipe close on other end by checking if a read() 00383 call would not block by calling select(). */ 00384 00385 FD_ZERO(&r_fds); 00386 FD_SET(winbindd_fd, &r_fds); 00387 ZERO_STRUCT(tv); 00388 00389 if (select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv) == -1) { 00390 close_sock(); 00391 return -1; /* Select error */ 00392 } 00393 00394 /* Write should be OK if fd not available for reading */ 00395 00396 if (!FD_ISSET(winbindd_fd, &r_fds)) { 00397 00398 /* Do the write */ 00399 00400 result = write(winbindd_fd, 00401 (char *)buffer + nwritten, 00402 count - nwritten); 00403 00404 if ((result == -1) || (result == 0)) { 00405 00406 /* Write failed */ 00407 00408 close_sock(); 00409 return -1; 00410 } 00411 00412 nwritten += result; 00413 00414 } else { 00415 00416 /* Pipe has closed on remote end */ 00417 00418 close_sock(); 00419 goto restart; 00420 } 00421 } 00422 00423 return nwritten; 00424 }
static int read_sock | ( | void * | buffer, | |
int | count | |||
) | [static] |
wb_common.c の 428 行で定義されています。
参照先 close_sock()・result・winbindd_fd.
参照元 read_reply().
00429 { 00430 int nread = 0; 00431 int total_time = 0, selret; 00432 00433 if (winbindd_fd == -1) { 00434 return -1; 00435 } 00436 00437 /* Read data from socket */ 00438 while(nread < count) { 00439 struct timeval tv; 00440 fd_set r_fds; 00441 00442 /* Catch pipe close on other end by checking if a read() 00443 call would not block by calling select(). */ 00444 00445 FD_ZERO(&r_fds); 00446 FD_SET(winbindd_fd, &r_fds); 00447 ZERO_STRUCT(tv); 00448 /* Wait for 5 seconds for a reply. May need to parameterise this... */ 00449 tv.tv_sec = 5; 00450 00451 if ((selret = select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv)) == -1) { 00452 close_sock(); 00453 return -1; /* Select error */ 00454 } 00455 00456 if (selret == 0) { 00457 /* Not ready for read yet... */ 00458 if (total_time >= 30) { 00459 /* Timeout */ 00460 close_sock(); 00461 return -1; 00462 } 00463 total_time += 5; 00464 continue; 00465 } 00466 00467 if (FD_ISSET(winbindd_fd, &r_fds)) { 00468 00469 /* Do the Read */ 00470 00471 int result = read(winbindd_fd, (char *)buffer + nread, 00472 count - nread); 00473 00474 if ((result == -1) || (result == 0)) { 00475 00476 /* Read failed. I think the only useful thing we 00477 can do here is just return -1 and fail since the 00478 transaction has failed half way through. */ 00479 00480 close_sock(); 00481 return -1; 00482 } 00483 00484 nread += result; 00485 00486 } 00487 } 00488 00489 return nread; 00490 }
int read_reply | ( | struct winbindd_response * | response | ) |
wb_common.c の 494 行で定義されています。
参照先 winbindd_response::data・winbindd_response::extra_data・free_response()・winbindd_response::length・read_sock().
参照元 pam_winbind_request()・winbindd_get_response().
00495 { 00496 int result1, result2 = 0; 00497 00498 if (!response) { 00499 return -1; 00500 } 00501 00502 /* Read fixed length response */ 00503 00504 if ((result1 = read_sock(response, sizeof(struct winbindd_response))) 00505 == -1) { 00506 00507 return -1; 00508 } 00509 00510 /* We actually send the pointer value of the extra_data field from 00511 the server. This has no meaning in the client's address space 00512 so we clear it out. */ 00513 00514 response->extra_data.data = NULL; 00515 00516 /* Read variable length response */ 00517 00518 if (response->length > sizeof(struct winbindd_response)) { 00519 int extra_data_len = response->length - 00520 sizeof(struct winbindd_response); 00521 00522 /* Mallocate memory for extra data */ 00523 00524 if (!(response->extra_data.data = malloc(extra_data_len))) { 00525 return -1; 00526 } 00527 00528 if ((result2 = read_sock(response->extra_data.data, extra_data_len)) 00529 == -1) { 00530 free_response(response); 00531 return -1; 00532 } 00533 } 00534 00535 /* Return total amount of data read */ 00536 00537 return result1 + result2; 00538 }
NSS_STATUS winbindd_send_request | ( | int | req_type, | |
int | need_priv, | |||
struct winbindd_request * | request | |||
) |
wb_common.c の 556 行で定義されています。
参照先 errno・winbindd_request::flags・init_request()・NSS_STATUS_NOTFOUND・NSS_STATUS_SUCCESS・NSS_STATUS_UNAVAIL・winbind_env_set()・write_sock().
参照元 send_next_request()・winbindd_priv_request_response()・winbindd_request_response().
00558 { 00559 struct winbindd_request lrequest; 00560 00561 /* Check for our tricky environment variable */ 00562 00563 if (winbind_env_set()) { 00564 return NSS_STATUS_NOTFOUND; 00565 } 00566 00567 if (!request) { 00568 ZERO_STRUCT(lrequest); 00569 request = &lrequest; 00570 } 00571 00572 /* Fill in request and send down pipe */ 00573 00574 init_request(request, req_type); 00575 00576 if (write_sock(request, sizeof(*request), 00577 request->flags & WBFLAG_RECURSE, need_priv) == -1) { 00578 /* Set ENOENT for consistency. Required by some apps */ 00579 errno = ENOENT; 00580 00581 return NSS_STATUS_UNAVAIL; 00582 } 00583 00584 if ((request->extra_len != 0) && 00585 (write_sock(request->extra_data.data, request->extra_len, 00586 request->flags & WBFLAG_RECURSE, need_priv) == -1)) { 00587 /* Set ENOENT for consistency. Required by some apps */ 00588 errno = ENOENT; 00589 00590 return NSS_STATUS_UNAVAIL; 00591 } 00592 00593 return NSS_STATUS_SUCCESS; 00594 }
NSS_STATUS winbindd_get_response | ( | struct winbindd_response * | response | ) |
wb_common.c の 600 行で定義されています。
参照先 errno・free_response()・init_response()・NSS_STATUS_NOTFOUND・NSS_STATUS_SUCCESS・NSS_STATUS_UNAVAIL・read_reply()・winbindd_response::result・WINBINDD_OK.
参照元 winbind_callback()・winbindd_priv_request_response()・winbindd_request_response().
00601 { 00602 struct winbindd_response lresponse; 00603 00604 if (!response) { 00605 ZERO_STRUCT(lresponse); 00606 response = &lresponse; 00607 } 00608 00609 init_response(response); 00610 00611 /* Wait for reply */ 00612 if (read_reply(response) == -1) { 00613 /* Set ENOENT for consistency. Required by some apps */ 00614 errno = ENOENT; 00615 00616 return NSS_STATUS_UNAVAIL; 00617 } 00618 00619 /* Throw away extra data if client didn't request it */ 00620 if (response == &lresponse) { 00621 free_response(response); 00622 } 00623 00624 /* Copy reply data from socket */ 00625 if (response->result != WINBINDD_OK) { 00626 return NSS_STATUS_NOTFOUND; 00627 } 00628 00629 return NSS_STATUS_SUCCESS; 00630 }
NSS_STATUS winbindd_request_response | ( | int | req_type, | |
struct winbindd_request * | request, | |||
struct winbindd_response * | response | |||
) |
wb_common.c の 634 行で定義されています。
参照先 NSS_STATUS_SUCCESS・NSS_STATUS_UNAVAIL・status・winbindd_get_response()・winbindd_send_request().
00637 { 00638 NSS_STATUS status = NSS_STATUS_UNAVAIL; 00639 int count = 0; 00640 00641 while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) { 00642 status = winbindd_send_request(req_type, 0, request); 00643 if (status != NSS_STATUS_SUCCESS) 00644 return(status); 00645 status = winbindd_get_response(response); 00646 count += 1; 00647 } 00648 00649 return status; 00650 }
NSS_STATUS winbindd_priv_request_response | ( | int | req_type, | |
struct winbindd_request * | request, | |||
struct winbindd_response * | response | |||
) |
wb_common.c の 652 行で定義されています。
参照先 NSS_STATUS_SUCCESS・NSS_STATUS_UNAVAIL・status・winbindd_get_response()・winbindd_send_request().
00655 { 00656 NSS_STATUS status = NSS_STATUS_UNAVAIL; 00657 int count = 0; 00658 00659 while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) { 00660 status = winbindd_send_request(req_type, 1, request); 00661 if (status != NSS_STATUS_SUCCESS) 00662 return(status); 00663 status = winbindd_get_response(response); 00664 count += 1; 00665 } 00666 00667 return status; 00668 }
int winbindd_fd = -1 |
wb_common.c の 35 行で定義されています。
参照元 close_sock()・read_sock()・wbinfo_ping()・winbind_open_pipe_sock()・write_sock().
int is_privileged = 0 [static] |