📄 winbind_nss_linux.c
字号:
/* Get next entry from ntdom group database */static NSS_STATUSwinbind_getgrent(enum winbindd_cmd cmd, struct group *result, char *buffer, size_t buflen, int *errnop){ NSS_STATUS ret; static struct winbindd_request request; static int called_again; #ifdef DEBUG_NSS fprintf(stderr, "[%5d]: getgrent\n", getpid());#endif /* Return an entry from the cache if we have one, or if we are called again because we exceeded our static buffer. */ if ((ndx_gr_cache < num_gr_cache) || called_again) { goto return_result; } /* Else call winbindd to get a bunch of entries */ if (num_gr_cache > 0) { winbindd_free_response(&getgrent_response); } ZERO_STRUCT(request); ZERO_STRUCT(getgrent_response); request.data.num_entries = MAX_GETGRENT_USERS; ret = winbindd_request_response(cmd, &request, &getgrent_response); if (ret == NSS_STATUS_SUCCESS) { struct winbindd_gr *gr_cache; int mem_ofs; /* Fill cache */ ndx_gr_cache = 0; num_gr_cache = getgrent_response.data.num_entries; /* Return a result */ return_result: gr_cache = (struct winbindd_gr *) getgrent_response.extra_data.data; /* Check data is valid */ if (gr_cache == NULL) { ret = NSS_STATUS_NOTFOUND; goto done; } /* Fill group membership. The offset into the extra data for the group membership is the reported offset plus the size of all the winbindd_gr records returned. */ mem_ofs = gr_cache[ndx_gr_cache].gr_mem_ofs + num_gr_cache * sizeof(struct winbindd_gr); ret = fill_grent(result, &gr_cache[ndx_gr_cache], ((char *)getgrent_response.extra_data.data)+mem_ofs, &buffer, &buflen); /* Out of memory - try again */ if (ret == NSS_STATUS_TRYAGAIN) { called_again = true; *errnop = errno = ERANGE; goto done; } *errnop = 0; called_again = false; ndx_gr_cache++; /* If we've finished with this lot of results free cache */ if (ndx_gr_cache == num_gr_cache) { ndx_gr_cache = num_gr_cache = 0; winbindd_free_response(&getgrent_response); } } done:#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: getgrent returns %s (%d)\n", getpid(), nss_err_str(ret), ret);#endif return ret;}NSS_STATUS_nss_winbind_getgrent_r(struct group *result, char *buffer, size_t buflen, int *errnop){ return winbind_getgrent(WINBINDD_GETGRENT, result, buffer, buflen, errnop);}NSS_STATUS_nss_winbind_getgrlst_r(struct group *result, char *buffer, size_t buflen, int *errnop){ return winbind_getgrent(WINBINDD_GETGRLST, result, buffer, buflen, errnop);}/* Return group struct from group name */NSS_STATUS_nss_winbind_getgrnam_r(const char *name, struct group *result, char *buffer, size_t buflen, int *errnop){ NSS_STATUS ret; static struct winbindd_response response; struct winbindd_request request; static int keep_response; #ifdef DEBUG_NSS fprintf(stderr, "[%5d]: getgrnam %s\n", getpid(), name);#endif /* If our static buffer needs to be expanded we are called again */ if (!keep_response) { /* Call for the first time */ ZERO_STRUCT(request); ZERO_STRUCT(response); strncpy(request.data.groupname, name, sizeof(request.data.groupname)); request.data.groupname [sizeof(request.data.groupname) - 1] = '\0'; ret = winbindd_request_response(WINBINDD_GETGRNAM, &request, &response); if (ret == NSS_STATUS_SUCCESS) { ret = fill_grent(result, &response.data.gr, (char *)response.extra_data.data, &buffer, &buflen); if (ret == NSS_STATUS_TRYAGAIN) { keep_response = true; *errnop = errno = ERANGE; goto done; } } } else { /* We've been called again */ ret = fill_grent(result, &response.data.gr, (char *)response.extra_data.data, &buffer, &buflen); if (ret == NSS_STATUS_TRYAGAIN) { keep_response = true; *errnop = errno = ERANGE; goto done; } keep_response = false; *errnop = 0; } winbindd_free_response(&response); done:#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: getgrnam %s returns %s (%d)\n", getpid(), name, nss_err_str(ret), ret);#endif return ret;}/* Return group struct from gid */NSS_STATUS_nss_winbind_getgrgid_r(gid_t gid, struct group *result, char *buffer, size_t buflen, int *errnop){ NSS_STATUS ret; static struct winbindd_response response; struct winbindd_request request; static int keep_response;#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: getgrgid %d\n", getpid(), gid);#endif /* If our static buffer needs to be expanded we are called again */ if (!keep_response) { /* Call for the first time */ ZERO_STRUCT(request); ZERO_STRUCT(response); request.data.gid = gid; ret = winbindd_request_response(WINBINDD_GETGRGID, &request, &response); if (ret == NSS_STATUS_SUCCESS) { ret = fill_grent(result, &response.data.gr, (char *)response.extra_data.data, &buffer, &buflen); if (ret == NSS_STATUS_TRYAGAIN) { keep_response = true; *errnop = errno = ERANGE; goto done; } } } else { /* We've been called again */ ret = fill_grent(result, &response.data.gr, (char *)response.extra_data.data, &buffer, &buflen); if (ret == NSS_STATUS_TRYAGAIN) { keep_response = true; *errnop = errno = ERANGE; goto done; } keep_response = false; *errnop = 0; } winbindd_free_response(&response); done:#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: getgrgid %d returns %s (%d)\n", getpid(), (unsigned int)gid, nss_err_str(ret), ret);#endif return ret;}/* Initialise supplementary groups */NSS_STATUS_nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop){ NSS_STATUS ret; struct winbindd_request request; struct winbindd_response response; int i;#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: initgroups %s (%d)\n", getpid(), user, group);#endif ZERO_STRUCT(request); ZERO_STRUCT(response); strncpy(request.data.username, user, sizeof(request.data.username) - 1); ret = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); if (ret == NSS_STATUS_SUCCESS) { int num_gids = response.data.num_entries; gid_t *gid_list = (gid_t *)response.extra_data.data;#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: initgroups %s: got NSS_STATUS_SUCCESS " "and %d gids\n", getpid(), user, num_gids);#endif if (gid_list == NULL) { ret = NSS_STATUS_NOTFOUND; goto done; } /* Copy group list to client */ for (i = 0; i < num_gids; i++) {#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: initgroups %s (%d): " "processing gid %d \n", getpid(), user, group, gid_list[i]);#endif /* Skip primary group */ if (gid_list[i] == group) { continue; } /* Filled buffer ? If so, resize. */ if (*start == *size) { long int newsize; gid_t *newgroups; newsize = 2 * (*size); if (limit > 0) { if (*size == limit) { goto done; } if (newsize > limit) { newsize = limit; } } newgroups = (gid_t *) realloc((*groups), newsize * sizeof(**groups)); if (!newgroups) { *errnop = ENOMEM; ret = NSS_STATUS_NOTFOUND; goto done; } *groups = newgroups; *size = newsize; } /* Add to buffer */ (*groups)[*start] = gid_list[i]; *start += 1; } } /* Back to your regularly scheduled programming */ done:#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: initgroups %s returns %s (%d)\n", getpid(), user, nss_err_str(ret), ret);#endif return ret;}/* return a list of group SIDs for a user SID */NSS_STATUS_nss_winbind_getusersids(const char *user_sid, char **group_sids, int *num_groups, char *buffer, size_t buf_size, int *errnop){ NSS_STATUS ret; struct winbindd_request request; struct winbindd_response response;#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: getusersids %s\n", getpid(), user_sid);#endif ZERO_STRUCT(request); ZERO_STRUCT(response); strncpy(request.data.sid, user_sid,sizeof(request.data.sid) - 1); request.data.sid[sizeof(request.data.sid) - 1] = '\0'; ret = winbindd_request_response(WINBINDD_GETUSERSIDS, &request, &response); if (ret != NSS_STATUS_SUCCESS) { goto done; } if (buf_size < response.length - sizeof(response)) { ret = NSS_STATUS_TRYAGAIN; errno = *errnop = ERANGE; goto done; } *num_groups = response.data.num_entries; *group_sids = buffer; memcpy(buffer, response.extra_data.data, response.length - sizeof(response)); errno = *errnop = 0; done: winbindd_free_response(&response); return ret;}/* map a user or group name to a SID string */NSS_STATUS_nss_winbind_nametosid(const char *name, char **sid, char *buffer, size_t buflen, int *errnop){ NSS_STATUS ret; struct winbindd_response response; struct winbindd_request request;#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: nametosid %s\n", getpid(), name);#endif ZERO_STRUCT(response); ZERO_STRUCT(request); strncpy(request.data.name.name, name, sizeof(request.data.name.name) - 1); request.data.name.name[sizeof(request.data.name.name) - 1] = '\0'; ret = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; } if (buflen < strlen(response.data.sid.sid)+1) { ret = NSS_STATUS_TRYAGAIN; *errnop = errno = ERANGE; goto failed; } *errnop = errno = 0; *sid = buffer; strcpy(*sid, response.data.sid.sid);failed: winbindd_free_response(&response); return ret;}/* map a sid string to a user or group name */NSS_STATUS_nss_winbind_sidtoname(const char *sid, char **name, char *buffer, size_t buflen, int *errnop){ NSS_STATUS ret; struct winbindd_response response; struct winbindd_request request; static char sep_char; unsigned needed;#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: sidtoname %s\n", getpid(), sid);#endif ZERO_STRUCT(response); ZERO_STRUCT(request); /* we need to fetch the separator first time through */ if (!sep_char) { ret = winbindd_request_response(WINBINDD_INFO, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; } sep_char = response.data.info.winbind_separator; winbindd_free_response(&response); } strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); request.data.sid[sizeof(request.data.sid) - 1] = '\0'; ret = winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; } needed = strlen(response.data.name.dom_name) + strlen(response.data.name.name) + 2; if (buflen < needed) { ret = NSS_STATUS_TRYAGAIN; *errnop = errno = ERANGE; goto failed; } snprintf(buffer, needed, "%s%c%s", response.data.name.dom_name, sep_char, response.data.name.name); *name = buffer; *errnop = errno = 0;failed: winbindd_free_response(&response); return ret;}/* map a sid to a uid */NSS_STATUS_nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop){ NSS_STATUS ret; struct winbindd_response response; struct winbindd_request request;#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: sidtouid %s\n", getpid(), sid);#endif ZERO_STRUCT(request); ZERO_STRUCT(response); strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); request.data.sid[sizeof(request.data.sid) - 1] = '\0'; ret = winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; } *uid = response.data.uid;failed: return ret;}/* map a sid to a gid */NSS_STATUS_nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop){ NSS_STATUS ret; struct winbindd_response response; struct winbindd_request request;#ifdef DEBUG_NSS fprintf(stderr, "[%5d]: sidtogid %s\n", getpid(), sid);#endif ZERO_STRUCT(request); ZERO_STRUCT(response); strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); request.data.sid[sizeof(request.data.sid) - 1] = '\0'; ret = winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; } *gid = response.data.gid;failed: return ret;}/* map a uid to a SID string */NSS_STATUS_nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer, size_t buflen, int *errnop){ NSS_STATUS ret; struct winbindd_response response; struct winbindd_request request;#ifdef DEBUG_NSS fprintf(stderr, "[%5u]: uidtosid %u\n", (unsigned int)getpid(), (unsigned int)uid);#endif ZERO_STRUCT(response); ZERO_STRUCT(request); request.data.uid = uid; ret = winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; } if (buflen < strlen(response.data.sid.sid)+1) { ret = NSS_STATUS_TRYAGAIN; *errnop = errno = ERANGE; goto failed; } *errnop = errno = 0; *sid = buffer; strcpy(*sid, response.data.sid.sid);failed: winbindd_free_response(&response); return ret;}/* map a gid to a SID string */NSS_STATUS_nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer, size_t buflen, int *errnop){ NSS_STATUS ret; struct winbindd_response response; struct winbindd_request request;#ifdef DEBUG_NSS fprintf(stderr, "[%5u]: gidtosid %u\n", (unsigned int)getpid(), (unsigned int)gid);#endif ZERO_STRUCT(response); ZERO_STRUCT(request); request.data.gid = gid; ret = winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; } if (buflen < strlen(response.data.sid.sid)+1) { ret = NSS_STATUS_TRYAGAIN; *errnop = errno = ERANGE; goto failed; } *errnop = errno = 0; *sid = buffer; strcpy(*sid, response.data.sid.sid);failed: winbindd_free_response(&response); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -