nfs-ganesha 1.4

nfs4_op_secinfo.c

Go to the documentation of this file.
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 
00037 #ifdef HAVE_CONFIG_H
00038 #include "config.h"
00039 #endif
00040 
00041 #ifdef _SOLARIS
00042 #include "solaris_port.h"
00043 #endif
00044 
00045 #include <stdio.h>
00046 #include <string.h>
00047 #include <pthread.h>
00048 #include <fcntl.h>
00049 #include <sys/file.h>           /* for having FNDELAY */
00050 #include "HashData.h"
00051 #include "HashTable.h"
00052 #include "log.h"
00053 #include "ganesha_rpc.h"
00054 #include "nfs23.h"
00055 #include "nfs4.h"
00056 #include "mount.h"
00057 #include "nfs_core.h"
00058 #include "cache_inode.h"
00059 #include "nfs_exports.h"
00060 #include "nfs_creds.h"
00061 #include "nfs_proto_functions.h"
00062 #include "nfs_proto_tools.h"
00063 #include "nfs_tools.h"
00064 #include "sal_functions.h"
00065 
00078 #define arg_SECINFO4 op->nfs_argop4_u.opsecinfo
00079 #define res_SECINFO4 resp->nfs_resop4_u.opsecinfo
00080 
00081 extern gss_OID_desc krb5oid;
00082 
00083 int nfs4_op_secinfo(struct nfs_argop4 *op,
00084                     compound_data_t * data, struct nfs_resop4 *resp)
00085 {
00086   char __attribute__ ((__unused__)) funcname[] = "nfs4_op_secinfo";
00087 
00088   fsal_name_t secinfo_fh_name;
00089   cache_inode_status_t cache_status;
00090   cache_entry_t *entry_src;
00091   fsal_attrib_list_t attr_secinfo;
00092   sec_oid4 v5oid = {krb5oid.length, (char *)krb5oid.elements};
00093   int num_entry = 0;
00094 
00095   resp->resop = NFS4_OP_SECINFO;
00096   res_SECINFO4.status = NFS4_OK;
00097 
00098   /* Read name from uft8 strings, if one is empty then returns NFS4ERR_INVAL */
00099   if(arg_SECINFO4.name.utf8string_len == 0)
00100     {
00101       res_SECINFO4.status = NFS4ERR_INVAL;
00102       return res_SECINFO4.status;
00103     }
00104 
00105   /*
00106    * Do basic checks on a filehandle
00107    * SecInfo is done only on a directory
00108    */
00109   res_SECINFO4.status = nfs4_sanity_check_FH(data, DIRECTORY);
00110   if(res_SECINFO4.status != NFS4_OK)
00111     return res_SECINFO4.status;
00112 
00113   if (nfs_in_grace())
00114     {
00115       res_SECINFO4.status = NFS4ERR_GRACE;
00116       return res_SECINFO4.status;
00117     }
00118 
00119   /* get the names from the RPC input */
00120   if((cache_status =
00121       cache_inode_error_convert(FSAL_buffdesc2name
00122                                 ((fsal_buffdesc_t *) & arg_SECINFO4.name,
00123                                  &secinfo_fh_name))) != CACHE_INODE_SUCCESS)
00124     {
00125       res_SECINFO4.status = NFS4ERR_INVAL;
00126       return res_SECINFO4.status;
00127     }
00128 
00129   if((entry_src = cache_inode_lookup(data->current_entry,
00130                                          &secinfo_fh_name,
00131                                          &attr_secinfo,
00132                                          data->pcontext, &cache_status)) == NULL)
00133     {
00134       res_SECINFO4.status = nfs4_Errno(cache_status);
00135       return res_SECINFO4.status;
00136     }
00137 
00138   /* get the number of entries */
00139   if (data->pexport->options & EXPORT_OPTION_AUTH_NONE)
00140     num_entry++;
00141   if (data->pexport->options & EXPORT_OPTION_AUTH_UNIX)
00142     num_entry++;
00143   if (data->pexport->options & EXPORT_OPTION_RPCSEC_GSS_NONE)
00144     num_entry++;
00145   if (data->pexport->options & EXPORT_OPTION_RPCSEC_GSS_INTG)
00146     num_entry++;
00147   if (data->pexport->options & EXPORT_OPTION_RPCSEC_GSS_PRIV)
00148     num_entry++;
00149 
00150   if((res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val =
00151       gsh_calloc(num_entry, sizeof(secinfo4))) == NULL)
00152     {
00153       res_SECINFO4.status = NFS4ERR_SERVERFAULT;
00154       cache_inode_put(entry_src);
00155       return res_SECINFO4.status;
00156     }
00157 
00158   /* XXX we have the opportunity to associate a preferred security triple
00159    * with a specific fs/export.  For now, list all implemented. */
00160   int idx=0;
00161   if (data->pexport->options & EXPORT_OPTION_AUTH_NONE)
00162       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx++].flavor = AUTH_NONE;
00163   if (data->pexport->options & EXPORT_OPTION_AUTH_UNIX)
00164       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx++].flavor = AUTH_UNIX;
00165   if (data->pexport->options & EXPORT_OPTION_RPCSEC_GSS_NONE)
00166     {
00167       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx].flavor = RPCSEC_GSS;
00168       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx].secinfo4_u.flavor_info.service = RPCSEC_GSS_SVC_NONE;
00169       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx].secinfo4_u.flavor_info.qop = GSS_C_QOP_DEFAULT;
00170       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx++].secinfo4_u.flavor_info.oid = v5oid;
00171     }
00172   if (data->pexport->options & EXPORT_OPTION_RPCSEC_GSS_INTG)
00173     {
00174       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx].flavor = RPCSEC_GSS;
00175       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx].secinfo4_u.flavor_info.service = RPCSEC_GSS_SVC_INTEGRITY;
00176       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx].secinfo4_u.flavor_info.qop = GSS_C_QOP_DEFAULT;
00177       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx++].secinfo4_u.flavor_info.oid = v5oid;
00178     }
00179   if (data->pexport->options & EXPORT_OPTION_RPCSEC_GSS_PRIV)
00180     {
00181       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx].flavor = RPCSEC_GSS;
00182       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx].secinfo4_u.flavor_info.service = RPCSEC_GSS_SVC_PRIVACY;
00183       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx].secinfo4_u.flavor_info.qop = GSS_C_QOP_DEFAULT;
00184       res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_val[idx++].secinfo4_u.flavor_info.oid = v5oid;
00185     }
00186   res_SECINFO4.SECINFO4res_u.resok4.SECINFO4resok_len = idx;
00187 
00188   cache_inode_put(entry_src);
00189 
00190   return res_SECINFO4.status;
00191 }                               /* nfs4_op_secinfo */
00192 
00203 void nfs4_op_secinfo_Free(SECINFO4res * resp)
00204 {
00205   /* Nothing to be done */
00206   return;
00207 }                               /* nfs4_op_secinfo_Free */