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 "includes.h"
00025 #include "winbindd.h"
00026
00027 #undef DBGC_CLASS
00028 #define DBGC_CLASS DBGC_WINBIND
00029
00030
00031
00032 static int wins_lookup_open_socket_in(void)
00033 {
00034 struct sockaddr_in sock;
00035 int val=1;
00036 int res;
00037
00038 memset((char *)&sock,'\0',sizeof(sock));
00039
00040 #ifdef HAVE_SOCK_SIN_LEN
00041 sock.sin_len = sizeof(sock);
00042 #endif
00043 sock.sin_port = 0;
00044 sock.sin_family = AF_INET;
00045 sock.sin_addr.s_addr = interpret_addr("0.0.0.0");
00046 res = socket(AF_INET, SOCK_DGRAM, 0);
00047 if (res == -1)
00048 return -1;
00049
00050 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val));
00051 #ifdef SO_REUSEPORT
00052 setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val));
00053 #endif
00054
00055
00056
00057 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) {
00058 close(res);
00059 return(-1);
00060 }
00061
00062 set_socket_options(res,"SO_BROADCAST");
00063
00064 return res;
00065 }
00066
00067
00068 static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count)
00069 {
00070 int fd;
00071 struct in_addr ip;
00072 struct nmb_name nname;
00073 NODE_STATUS_STRUCT *status;
00074
00075 fd = wins_lookup_open_socket_in();
00076 if (fd == -1)
00077 return NULL;
00078
00079 make_nmb_name(&nname, "*", 0);
00080 ip = *interpret_addr2(addr);
00081 status = node_status_query(fd,&nname,ip, count, NULL);
00082
00083 close(fd);
00084 return status;
00085 }
00086
00087 static struct in_addr *lookup_byname_backend(const char *name, int *count)
00088 {
00089 int fd;
00090 struct ip_service *ret = NULL;
00091 struct in_addr *return_ip = NULL;
00092 int j, i, flags = 0;
00093
00094 *count = 0;
00095
00096
00097 if (resolve_wins(name,0x20,&ret,count)) {
00098 if ( *count == 0 )
00099 return NULL;
00100 if ( (return_ip = SMB_MALLOC_ARRAY(struct in_addr, *count)) == NULL ) {
00101 free( ret );
00102 return NULL;
00103 }
00104
00105
00106 for ( i=0; i<(*count); i++ )
00107 return_ip[i] = ret[i].ip;
00108
00109 free( ret );
00110 return return_ip;
00111 }
00112
00113 fd = wins_lookup_open_socket_in();
00114 if (fd == -1) {
00115 return NULL;
00116 }
00117
00118
00119 for (j=iface_count() - 1;
00120 j >= 0;
00121 j--) {
00122 struct in_addr *bcast = iface_n_bcast(j);
00123 return_ip = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
00124 if (return_ip) {
00125 break;
00126 }
00127 }
00128
00129 close(fd);
00130 return return_ip;
00131 }
00132
00133
00134
00135 void winbindd_wins_byip(struct winbindd_cli_state *state)
00136 {
00137 fstring response;
00138 int i, count, maxlen, size;
00139 NODE_STATUS_STRUCT *status;
00140
00141
00142 state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
00143
00144 DEBUG(3, ("[%5lu]: wins_byip %s\n", (unsigned long)state->pid,
00145 state->request.data.winsreq));
00146
00147 *response = '\0';
00148 maxlen = sizeof(response) - 1;
00149
00150 if ((status = lookup_byaddr_backend(state->request.data.winsreq, &count))){
00151 size = strlen(state->request.data.winsreq);
00152 if (size > maxlen) {
00153 SAFE_FREE(status);
00154 request_error(state);
00155 return;
00156 }
00157 fstrcat(response,state->request.data.winsreq);
00158 fstrcat(response,"\t");
00159 for (i = 0; i < count; i++) {
00160
00161 if (status[i].flags & 0x80) continue;
00162 if (status[i].type == 0x20) {
00163 size = sizeof(status[i].name) + strlen(response);
00164 if (size > maxlen) {
00165 SAFE_FREE(status);
00166 request_error(state);
00167 return;
00168 }
00169 fstrcat(response, status[i].name);
00170 fstrcat(response, " ");
00171 }
00172 }
00173
00174 response[strlen(response)-1] = '\n';
00175 SAFE_FREE(status);
00176 }
00177 fstrcpy(state->response.data.winsresp,response);
00178 request_ok(state);
00179 }
00180
00181
00182
00183 void winbindd_wins_byname(struct winbindd_cli_state *state)
00184 {
00185 struct in_addr *ip_list;
00186 int i, count, maxlen, size;
00187 fstring response;
00188 char * addr;
00189
00190
00191 state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
00192
00193 DEBUG(3, ("[%5lu]: wins_byname %s\n", (unsigned long)state->pid,
00194 state->request.data.winsreq));
00195
00196 *response = '\0';
00197 maxlen = sizeof(response) - 1;
00198
00199 if ((ip_list = lookup_byname_backend(state->request.data.winsreq,&count))){
00200 for (i = count; i ; i--) {
00201 addr = inet_ntoa(ip_list[i-1]);
00202 size = strlen(addr);
00203 if (size > maxlen) {
00204 SAFE_FREE(ip_list);
00205 request_error(state);
00206 return;
00207 }
00208 if (i != 0) {
00209
00210
00211
00212 if (strlen(response))
00213 response[strlen(response)-1] = ' ';
00214 }
00215 fstrcat(response,addr);
00216 fstrcat(response,"\t");
00217 }
00218 size = strlen(state->request.data.winsreq) + strlen(response);
00219 if (size > maxlen) {
00220 SAFE_FREE(ip_list);
00221 request_error(state);
00222 return;
00223 }
00224 fstrcat(response,state->request.data.winsreq);
00225 fstrcat(response,"\n");
00226 SAFE_FREE(ip_list);
00227 } else {
00228 request_error(state);
00229 return;
00230 }
00231
00232 fstrcpy(state->response.data.winsresp,response);
00233
00234 request_ok(state);
00235 }