nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * Copyright CEA/DAM/DIF (2008) 00005 * contributeur : Philippe DENIEL philippe.deniel@cea.fr 00006 * Thomas LEIBOVICI thomas.leibovici@cea.fr 00007 * 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 3 of the License, or (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 GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 * 00023 * --------------------------------------- 00024 */ 00025 00038 #ifdef HAVE_CONFIG_H 00039 #include "config.h" 00040 #endif 00041 00042 #ifdef _SOLARIS 00043 #include "solaris_port.h" 00044 #endif 00045 00046 #include <stdio.h> 00047 #include <string.h> 00048 #include <pthread.h> 00049 #include <fcntl.h> 00050 #include <sys/file.h> /* for having FNDELAY */ 00051 #include <sys/types.h> 00052 #include <sys/socket.h> 00053 #include <arpa/inet.h> 00054 00055 #include "HashData.h" 00056 #include "HashTable.h" 00057 #include "log.h" 00058 #include "nfs23.h" 00059 #include "nfs4.h" 00060 #include "nfs_core.h" 00061 #include "cache_inode.h" 00062 #include "nfs_exports.h" 00063 #include "nfs_creds.h" 00064 #include "nfs_tools.h" 00065 #include "mount.h" 00066 #include "nfs_proto_functions.h" 00067 00082 int mnt_Export(nfs_arg_t *parg, 00083 exportlist_t *pexport, 00084 fsal_op_context_t *pcontext, 00085 nfs_worker_data_t *pworker, 00086 struct svc_req *preq, 00087 nfs_res_t * pres) 00088 { 00089 00090 exportlist_t *p_current_item = pexport; /* the current export item. */ 00091 00092 exports p_exp_out = NULL; /* Pointer to the first export entry. */ 00093 exports p_exp_current = NULL; /* Pointer to the last export entry. */ 00094 00095 unsigned int i; 00096 00097 LogDebug(COMPONENT_NFSPROTO, "REQUEST PROCESSING: Calling mnt_Export"); 00098 00099 /* paranoid command, to avoid parasites in the result structure. */ 00100 memset(pres, 0, sizeof(nfs_res_t)); 00101 00102 /* for each existing export entry */ 00103 while(p_current_item) 00104 { 00105 00106 exports new_expnode; /* the export node to be added to the list */ 00107 int buffsize; 00108 00109 new_expnode = gsh_calloc(1,sizeof(exportnode)); 00110 00111 /* ---- ex_dir ------ */ 00112 00113 /* we set the export path */ 00114 00115 LogFullDebug(COMPONENT_NFSPROTO, 00116 "MNT_EXPORT: Export entry: %s | Numclients: %d | PtrClients: %p", 00117 p_current_item->fullpath, p_current_item->clients.num_clients, 00118 p_current_item->clients.clientarray); 00119 00120 buffsize = strlen(p_current_item->fullpath) + 1; 00121 00122 new_expnode->ex_dir = gsh_calloc(1,buffsize); 00123 00124 strncpy(new_expnode->ex_dir, p_current_item->fullpath, buffsize); 00125 00126 /* ---- ex_groups ---- */ 00127 00128 /* we convert the group list */ 00129 00130 if(p_current_item->clients.num_clients > 0) 00131 { 00132 00133 /* Alias, to make the code slim... */ 00134 exportlist_client_t *p_clients = &(p_current_item->clients); 00135 00136 /* allocates the memory for all the groups, once for all */ 00137 new_expnode->ex_groups = 00138 gsh_calloc(p_clients->num_clients, sizeof(groupnode)); 00139 00140 for(i = 0; i < p_clients->num_clients; i++) 00141 { 00142 00143 /* ---- gr_next ----- */ 00144 00145 if((i + 1) == p_clients->num_clients) /* this is the last item */ 00146 new_expnode->ex_groups[i].gr_next = NULL; 00147 else /* other items point to the next memory slot */ 00148 new_expnode->ex_groups[i].gr_next = &(new_expnode->ex_groups[i + 1]); 00149 00150 /* ---- gr_name ----- */ 00151 00152 switch (p_clients->clientarray[i].type) 00153 { 00154 case HOSTIF_CLIENT: 00155 00156 /* allocates target buffer (+1 for security ) */ 00157 new_expnode->ex_groups[i].gr_name 00158 = gsh_calloc(1, INET_ADDRSTRLEN + 1); 00159 00160 if(inet_ntop 00161 (AF_INET, &(p_clients->clientarray[i].client.hostif.clientaddr), 00162 new_expnode->ex_groups[i].gr_name, INET_ADDRSTRLEN) == NULL) 00163 { 00164 strncpy(new_expnode->ex_groups[i].gr_name, "Invalid Host address", 00165 MAXHOSTNAMELEN); 00166 } 00167 00168 break; 00169 00170 case NETWORK_CLIENT: 00171 00172 /* allocates target buffer (+1 for security ) */ 00173 new_expnode->ex_groups[i].gr_name 00174 = gsh_calloc(1, INET_ADDRSTRLEN + 1); 00175 00176 if(inet_ntop 00177 (AF_INET, &(p_clients->clientarray[i].client.network.netaddr), 00178 new_expnode->ex_groups[i].gr_name, INET_ADDRSTRLEN) == NULL) 00179 { 00180 strncpy(new_expnode->ex_groups[i].gr_name, 00181 "Invalid Network address", MAXHOSTNAMELEN); 00182 } 00183 00184 break; 00185 00186 case NETGROUP_CLIENT: 00187 00188 /* allocates target buffer */ 00189 00190 new_expnode->ex_groups[i].gr_name 00191 = gsh_calloc(1, MAXHOSTNAMELEN); 00192 00193 strncpy(new_expnode->ex_groups[i].gr_name, 00194 p_clients->clientarray[i].client.netgroup.netgroupname, 00195 MAXHOSTNAMELEN); 00196 00197 break; 00198 00199 case WILDCARDHOST_CLIENT: 00200 00201 /* allocates target buffer */ 00202 new_expnode->ex_groups[i].gr_name 00203 = gsh_calloc(1, MAXHOSTNAMELEN); 00204 00205 strncpy(new_expnode->ex_groups[i].gr_name, 00206 p_clients->clientarray[i].client.wildcard.wildcard, 00207 MAXHOSTNAMELEN); 00208 break; 00209 00210 case GSSPRINCIPAL_CLIENT: 00211 00212 new_expnode->ex_groups[i].gr_name 00213 = gsh_calloc(1, MAXHOSTNAMELEN); 00214 00215 strncpy(new_expnode->ex_groups[i].gr_name, 00216 p_clients->clientarray[i].client.gssprinc.princname, 00217 MAXHOSTNAMELEN); 00218 00219 break; 00220 00221 default: 00222 00223 /* @todo : free allocated resources */ 00224 00225 LogCrit(COMPONENT_NFSPROTO, 00226 "MNT_EXPORT: Unknown export entry type: %d", 00227 p_clients->clientarray[i].type); 00228 00229 new_expnode->ex_groups[i].gr_name = NULL; 00230 00231 return NFS_REQ_DROP; 00232 } 00233 00234 } 00235 00236 } 00237 else 00238 { 00239 /* There are no groups for this export entry. */ 00240 new_expnode->ex_groups = NULL; 00241 00242 } 00243 00244 /* ---- ex_next ----- */ 00245 00246 /* this is the last item in the list */ 00247 00248 new_expnode->ex_next = NULL; 00249 00250 /* we insert the export node to the export list */ 00251 00252 if(p_exp_out) 00253 { 00254 p_exp_current->ex_next = new_expnode; 00255 p_exp_current = new_expnode; 00256 } 00257 else 00258 { 00259 /* This is the first item in the list */ 00260 p_exp_out = new_expnode; 00261 p_exp_current = new_expnode; 00262 } 00263 00264 p_current_item = (exportlist_t *) (p_current_item->next); 00265 00266 } 00267 00268 /* return the pointer to the export list */ 00269 00270 pres->res_mntexport = p_exp_out; 00271 00272 return NFS_REQ_OK; 00273 00274 } /* mnt_Export */ 00275 00284 void mnt_Export_Free(nfs_res_t * pres) 00285 { 00286 00287 exports e = pres->res_mntexport; 00288 00289 while (e) 00290 { 00291 struct groupnode *g = e->ex_groups; 00292 exports n = e->ex_next; 00293 00294 while (g) 00295 { 00296 gsh_free(g->gr_name); 00297 g = g->gr_next; 00298 } 00299 gsh_free(e->ex_groups); 00300 gsh_free(e->ex_dir); 00301 gsh_free(e); 00302 00303 e = n; 00304 } 00305 } /* mnt_Export_Free */