nsswitch/winbindd_wins.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003 
00004    Winbind daemon - WINS related functions
00005 
00006    Copyright (C) Andrew Tridgell 1999
00007    Copyright (C) Herb Lewis 2002
00008    
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013    
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018    
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00022 */
00023 
00024 #include "includes.h"
00025 #include "winbindd.h"
00026 
00027 #undef DBGC_CLASS
00028 #define DBGC_CLASS DBGC_WINBIND
00029 
00030 /* Use our own create socket code so we don't recurse.... */
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 /* SO_REUSEPORT */
00054 
00055         /* now we've got a socket - we need to bind it */
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         /* always try with wins first */
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                 /* copy the IP addresses */
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         /* uggh, we have to broadcast to each interface in turn */
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 /* Get hostname from IP  */
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         /* Ensure null termination */
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                 /* ignore group names */
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             /* make last character a newline */
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 /* Get IP from hostname */
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         /* Ensure null termination */
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                         /* Clear out the newline character */
00210                         /* But only if there is something in there, 
00211                            otherwise we clobber something in the stack */
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 }

Sambaに対してSat Aug 29 21:23:11 2009に生成されました。  doxygen 1.4.7