diff options
-rw-r--r-- | source3/Makefile.in | 1 | ||||
-rw-r--r-- | source3/nsswitch/wbinfo.c | 68 | ||||
-rw-r--r-- | source3/nsswitch/winbind_nss.c | 39 | ||||
-rw-r--r-- | source3/nsswitch/winbindd.c | 5 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_nss.h | 8 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_proto.h | 9 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_wins.c | 68 |
7 files changed, 151 insertions, 47 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 41d42ecb83..7463447498 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -437,6 +437,7 @@ WINBINDD_OBJ1 = \ nsswitch/winbindd_sid.o \ nsswitch/winbindd_misc.o \ nsswitch/winbindd_cm.o \ + nsswitch/winbindd_wins.o \ nsswitch/winbindd_rpc.o \ nsswitch/winbindd_ads.o diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index b94b571805..56886872f1 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -137,6 +137,58 @@ static BOOL wbinfo_get_usergroups(char *user) return True; } +/* Convert NetBIOS name to IP */ + +static BOOL wbinfo_wins_byname(char *name) +{ + struct winbindd_request request; + struct winbindd_response response; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + /* Send request */ + + fstrcpy(request.data.winsreq, name); + + if (winbindd_request(WINBINDD_WINS_BYNAME, &request, &response) != + NSS_STATUS_SUCCESS) { + return False; + } + + /* Display response */ + + printf("%s\n", response.data.winsresp); + + return True; +} + +/* Convert IP to NetBIOS name */ + +static BOOL wbinfo_wins_byip(char *ip) +{ + struct winbindd_request request; + struct winbindd_response response; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + /* Send request */ + + fstrcpy(request.data.winsreq, ip); + + if (winbindd_request(WINBINDD_WINS_BYIP, &request, &response) != + NSS_STATUS_SUCCESS) { + return False; + } + + /* Display response */ + + printf("%s\n", response.data.winsresp); + + return True; +} + /* List trusted domains */ static BOOL wbinfo_list_domains(void) @@ -578,6 +630,8 @@ static void usage(void) d_printf("\t-g\t\t\tlists all domain groups\n"); d_printf("\t-n name\t\t\tconverts name to sid\n"); d_printf("\t-s sid\t\t\tconverts sid to name\n"); + d_printf("\t-N name\t\t\tconverts NetBIOS name to IP (WINS)\n"); + d_printf("\t-I name\t\t\tconverts IP address to NetBIOS name (WINS)\n"); d_printf("\t-U uid\t\t\tconverts uid to sid\n"); d_printf("\t-G gid\t\t\tconverts gid to sid\n"); d_printf("\t-S sid\t\t\tconverts sid to uid\n"); @@ -615,6 +669,8 @@ int main(int argc, char **argv) { "help", 'h', POPT_ARG_NONE, 0, 'h' }, { "domain-users", 'u', POPT_ARG_NONE, 0, 'u' }, { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g' }, + { "WINS-by-name", 'N', POPT_ARG_STRING, &string_arg, 'N' }, + { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I' }, { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n' }, { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's' }, { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U' }, @@ -701,6 +757,18 @@ int main(int argc, char **argv) return 1; } break; + case 'N': + if (!wbinfo_wins_byname(string_arg)) { + d_printf("Could not lookup WINS by name %s\n", string_arg); + return 1; + } + break; + case 'I': + if (!wbinfo_wins_byip(string_arg)) { + d_printf("Could not lookup WINS by IP %s\n", string_arg); + return 1; + } + break; case 'U': if (!wbinfo_uid_to_sid(int_arg)) { d_printf("Could not convert uid %d to sid\n", int_arg); diff --git a/source3/nsswitch/winbind_nss.c b/source3/nsswitch/winbind_nss.c index 8d33cd9b2f..0a49f5ec96 100644 --- a/source3/nsswitch/winbind_nss.c +++ b/source3/nsswitch/winbind_nss.c @@ -107,7 +107,7 @@ winbind_xid_lookup(int xid, struct winbindd_request **requestp) *last = dx->next; result = dx->rq; *requestp = dx->request; - free(dx); + SAFE_FREE(dx); } nsd_logprintf(NSD_LOG_LOW, "entering winbind_xid_lookup xid = %d rq = 0x%x, request = 0x%x\n", @@ -178,9 +178,9 @@ winbind_callback(nsd_file_t **rqp, int fd) struct winbindd_gr *gr = &response.data.gr; nsd_file_t *rq; NSS_STATUS status; - char result[1024]; + fstring result; char *members; - int i; + int i, maxlen; dequeue_request(); @@ -204,10 +204,17 @@ winbind_callback(nsd_file_t **rqp, int fd) rq->f_status = NS_NOTFOUND; return NSD_NEXT; } + + maxlen = sizeof(result) - 1; + switch ((int)rq->f_cmd_data) { + case WINBINDD_WINS_BYNAME: + case WINBINDD_WINS_BYIP: + snprintf(result,maxlen,"%s\n",response.data.winsresp); + break; case WINBINDD_GETPWUID: case WINBINDD_GETPWNAM: - snprintf(result,1023,"%s:%s:%d:%d:%s:%s:%s\n", + snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s\n", pw->pw_name, pw->pw_passwd, pw->pw_uid, @@ -222,7 +229,7 @@ winbind_callback(nsd_file_t **rqp, int fd) members = response.extra_data; else members = ""; - snprintf(result,1023,"%s:%s:%d:%s\n", + snprintf(result,maxlen,"%s:%s:%d:%s\n", gr->gr_name, gr->gr_passwd, gr->gr_gid, members); break; case WINBINDD_SETGRENT: @@ -244,7 +251,7 @@ winbind_callback(nsd_file_t **rqp, int fd) members = (char *)response.extra_data + (response.data.num_entries * sizeof(struct winbindd_gr)); for (i = 0; i < response.data.num_entries; i++) { - snprintf(result,1023,"%s:%s:%d:%s\n", + snprintf(result,maxlen,"%s:%s:%d:%s\n", gr->gr_name, gr->gr_passwd, gr->gr_gid, &members[gr->gr_mem_ofs]); nsd_logprintf(NSD_LOG_MIN, " GETGRENT %s\n",result); @@ -270,7 +277,7 @@ winbind_callback(nsd_file_t **rqp, int fd) return NSD_ERROR; } for (i = 0; i < response.data.num_entries; i++) { - snprintf(result,1023,"%s:%s:%d:%d:%s:%s:%s", + snprintf(result,maxlen,"%s:%s:%d:%d:%s:%s:%s", pw->pw_name, pw->pw_passwd, pw->pw_uid, @@ -338,7 +345,7 @@ send_next_request(nsd_file_t *rq, struct winbindd_request *request) nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) %d to = %d\n", rq->f_cmd_data, timeout); status = winbindd_send_request((int)rq->f_cmd_data,request); - free(request); + SAFE_FREE(request); if (status != NSS_STATUS_SUCCESS) { nsd_logprintf(NSD_LOG_MIN, @@ -407,12 +414,20 @@ int lookup(nsd_file_t *rq) } else if (strcasecmp(map,"group.bygid") == 0) { request->data.gid = atoi(key); rq->f_cmd_data = (void *)WINBINDD_GETGRGID; + } else if (strcasecmp(map,"hosts.byname") == 0) { + strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1); + request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0'; + rq->f_cmd_data = (void *)WINBINDD_WINS_BYNAME; + } else if (strcasecmp(map,"hosts.byaddr") == 0) { + strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1); + request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0'; + rq->f_cmd_data = (void *)WINBINDD_WINS_BYIP; } else { /* * Don't understand this map - just return not found */ nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) unknown table\n"); - free(request); + SAFE_FREE(request); rq->f_status = NS_NOTFOUND; return NSD_NEXT; } @@ -470,7 +485,7 @@ do_list(int state, nsd_file_t *rq) break; default: nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n"); - free(request); + SAFE_FREE(request); rq->f_status = NS_NOTFOUND; return NSD_NEXT; } @@ -488,7 +503,7 @@ do_list(int state, nsd_file_t *rq) break; default: nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n"); - free(request); + SAFE_FREE(request); rq->f_status = NS_NOTFOUND; return NSD_NEXT; } @@ -497,7 +512,7 @@ do_list(int state, nsd_file_t *rq) * Don't understand this map - just return not found */ nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown table\n"); - free(request); + SAFE_FREE(request); rq->f_status = NS_NOTFOUND; return NSD_NEXT; } diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index f7e92fc82d..7e1372614b 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -255,6 +255,11 @@ static struct dispatch_table dispatch_table[] = { { WINBINDD_INTERFACE_VERSION, winbindd_interface_version, "INTERFACE_VERSION" }, { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" }, + /* WINS functions */ + + { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" }, + { WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" }, + /* End of list */ { WINBINDD_NUM_CMDS, NULL, "NONE" } diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index 476dc71ab2..023d72306b 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -94,6 +94,11 @@ enum winbindd_cmd { WINBINDD_SHOW_SEQUENCE, /* display sequence numbers of domains */ + /* WINS commands */ + + WINBINDD_WINS_BYIP, + WINBINDD_WINS_BYNAME, + /* Placeholder for end of cmd list */ WINBINDD_NUM_CMDS @@ -107,6 +112,7 @@ struct winbindd_request { pid_t pid; /* pid of calling process */ union { + fstring winsreq; /* WINS request */ fstring username; /* getpwnam */ fstring groupname; /* getgrnam */ uid_t uid; /* getpwuid, uid_to_sid */ @@ -160,6 +166,8 @@ struct winbindd_response { union { int interface_version; /* Try to ensure this is always in the same spot... */ + fstring winsresp; /* WINS response */ + /* getpwnam, getpwuid */ struct winbindd_pw { diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h index 14edbfdd44..f12c56e8b1 100644 --- a/source3/nsswitch/winbindd_proto.h +++ b/source3/nsswitch/winbindd_proto.h @@ -1,5 +1,6 @@ #ifndef _WINBINDD_PROTO_H_ #define _WINBINDD_PROTO_H_ + /* This file is automatically generated with "make proto". DO NOT EDIT */ @@ -122,4 +123,10 @@ BOOL winbindd_param_init(void); BOOL check_domain_env(char *domain_env, char *domain); BOOL parse_domain_user(const char *domuser, fstring domain, fstring user); void fill_domain_username(fstring name, const char *domain, const char *user); -#endif /* _PROTO_H_ */ + +/* The following definitions come from nsswitch/winbindd_wins.c */ + +enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state); +enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state); + +#endif /* _WINBINDD_PROTO_H_ */ diff --git a/source3/nsswitch/winbindd_wins.c b/source3/nsswitch/winbindd_wins.c index 0aab4ddd65..af624170eb 100644 --- a/source3/nsswitch/winbindd_wins.c +++ b/source3/nsswitch/winbindd_wins.c @@ -94,7 +94,7 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count) return NULL; p = wins_srv_ip(); - if( !zero_ip(p) ) { + if( !is_zero_ip(p) ) { ret = name_query(fd,name,0x20,False,True, p, count); goto out; } @@ -124,43 +124,42 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count) enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state) { - char response[1024]; - int i, count, len, size; + fstring response; + int i, count, maxlen, size; struct node_status *status; DEBUG(3, ("[%5d]: wins_byip %s\n", state->pid, - state->request.data.name)); + state->request.data.winsreq)); *response = '\0'; - len = sizeof(response) - 2; + maxlen = sizeof(response) - 1; - if ((status = lookup_byaddr_backend(state->request.data.name, &count))){ - size = strlen(state->request.data.name) + 1; - if (size > len) { + if ((status = lookup_byaddr_backend(state->request.data.winsreq, &count))){ + size = strlen(state->request.data.winsreq); + if (size > maxlen) { SAFE_FREE(status); return WINBINDD_ERROR; } - len -= size; - safe_strcat(response,state->request.data.name,size); - safe_strcat(response,"\t",1); + safe_strcat(response,state->request.data.winsreq,maxlen); + safe_strcat(response,"\t",maxlen); for (i = 0; i < count; i++) { /* ignore group names */ if (status[i].flags & 0x80) continue; if (status[i].type == 0x20) { - size = sizeof(status[i].name) + 1; - if (size > len) { + size = sizeof(status[i].name) + strlen(response); + if (size > maxlen) { SAFE_FREE(status); return WINBINDD_ERROR; } - len -= size; - safe_strcat(response, status[i].name, size); - safe_strcat(response, " ", 1); + safe_strcat(response, status[i].name, maxlen); + safe_strcat(response, " ", maxlen); } } + /* make last character a newline */ response[strlen(response)-1] = '\n'; SAFE_FREE(status); } - fstrcpy(state->response.data.name.name,response); + fstrcpy(state->response.data.winsresp,response); return WINBINDD_OK; } @@ -169,42 +168,43 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state) enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state) { struct in_addr *ip_list; - int i, count, len, size; - char response[1024]; + int i, count, maxlen, size; + fstring response; char * addr; DEBUG(3, ("[%5d]: wins_byname %s\n", state->pid, - state->request.data.name)); + state->request.data.winsreq)); *response = '\0'; - len = sizeof(response) - 2; + maxlen = sizeof(response) - 1; - if ((ip_list = lookup_byname_backend(state->request.data.name,&count))){ + if ((ip_list = lookup_byname_backend(state->request.data.winsreq,&count))){ for (i = count; i ; i--) { addr = inet_ntoa(ip_list[i-1]); - size = strlen(addr) + 1; - if (size > len) { + size = strlen(addr); + if (size > maxlen) { SAFE_FREE(ip_list); return WINBINDD_ERROR; } - len -= size; - if (i != 0) - response[strlen(response)-1] = ' '; - safe_strcat(response,addr,size); - safe_strcat(response,"\t",1); + if (i != 0) { + /* Clear out the newline character */ + response[strlen(response)-1] = ' '; + } + safe_strcat(response,addr,maxlen); + safe_strcat(response,"\t",maxlen); } - size = strlen(state->request.data.name) + 1; - if (size > len) { + size = strlen(state->request.data.winsreq) + strlen(response); + if (size > maxlen) { SAFE_FREE(ip_list); return WINBINDD_ERROR; } - safe_strcat(response,state->request.data.name,size); - safe_strcat(response,"\n",1); + safe_strcat(response,state->request.data.winsreq,maxlen); + safe_strcat(response,"\n",maxlen); SAFE_FREE(ip_list); } else return WINBINDD_ERROR; - fstrcpy(state->response.data.name.name,response); + fstrcpy(state->response.data.winsresp,response); return WINBINDD_OK; } |