The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/ncpfs/ioctl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *  ioctl.c
    3  *
    4  *  Copyright (C) 1995, 1996 by Volker Lendecke
    5  *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
    6  *  Modified 1998, 1999 Wolfram Pienkoss for NLS
    7  *
    8  */
    9 
   10 #include <linux/config.h>
   11 
   12 #include <asm/uaccess.h>
   13 #include <linux/errno.h>
   14 #include <linux/fs.h>
   15 #include <linux/ioctl.h>
   16 #include <linux/sched.h>
   17 #include <linux/mm.h>
   18 #include <linux/highuid.h>
   19 #include <linux/vmalloc.h>
   20 
   21 #include <linux/ncp_fs.h>
   22 
   23 #include "ncplib_kernel.h"
   24 
   25 /* maximum limit for ncp_objectname_ioctl */
   26 #define NCP_OBJECT_NAME_MAX_LEN 4096
   27 /* maximum limit for ncp_privatedata_ioctl */
   28 #define NCP_PRIVATE_DATA_MAX_LEN 8192
   29 /* maximum negotiable packet size */
   30 #define NCP_PACKET_SIZE_INTERNAL 65536
   31 
   32 int ncp_ioctl(struct inode *inode, struct file *filp,
   33               unsigned int cmd, unsigned long arg)
   34 {
   35         struct ncp_server *server = NCP_SERVER(inode);
   36         int result;
   37         struct ncp_ioctl_request request;
   38         char* bouncebuffer;
   39 
   40         switch (cmd) {
   41         case NCP_IOC_NCPREQUEST:
   42 
   43                 if ((permission(inode, MAY_WRITE) != 0)
   44                     && (current->uid != server->m.mounted_uid)) {
   45                         return -EACCES;
   46                 }
   47                 if (copy_from_user(&request, (struct ncp_ioctl_request *) arg,
   48                                sizeof(request)))
   49                         return -EFAULT;
   50 
   51                 if ((request.function > 255)
   52                     || (request.size >
   53                   NCP_PACKET_SIZE - sizeof(struct ncp_request_header))) {
   54                         return -EINVAL;
   55                 }
   56                 bouncebuffer = vmalloc(NCP_PACKET_SIZE_INTERNAL);
   57                 if (!bouncebuffer)
   58                         return -ENOMEM;
   59                 if (copy_from_user(bouncebuffer, request.data, request.size)) {
   60                         vfree(bouncebuffer);
   61                         return -EFAULT;
   62                 }
   63                 ncp_lock_server(server);
   64 
   65                 /* FIXME: We hack around in the server's structures
   66                    here to be able to use ncp_request */
   67 
   68                 server->has_subfunction = 0;
   69                 server->current_size = request.size;
   70                 memcpy(server->packet, bouncebuffer, request.size);
   71 
   72                 result = ncp_request2(server, request.function, 
   73                         bouncebuffer, NCP_PACKET_SIZE_INTERNAL);
   74                 if (result < 0)
   75                         result = -EIO;
   76                 else
   77                         result = server->reply_size;
   78                 ncp_unlock_server(server);
   79                 DPRINTK("ncp_ioctl: copy %d bytes\n",
   80                         result);
   81                 if (result >= 0)
   82                         if (copy_to_user(request.data, bouncebuffer, result))
   83                                 result = -EFAULT;
   84                 vfree(bouncebuffer);
   85                 return result;
   86 
   87         case NCP_IOC_CONN_LOGGED_IN:
   88 
   89                 if (!capable(CAP_SYS_ADMIN))
   90                         return -EACCES;
   91                 if (!(server->m.int_flags & NCP_IMOUNT_LOGGEDIN_POSSIBLE))
   92                         return -EINVAL;
   93                 if (server->root_setuped)
   94                         return -EBUSY;
   95                 server->root_setuped = 1;
   96                 return ncp_conn_logged_in(inode->i_sb);
   97 
   98         case NCP_IOC_GET_FS_INFO:
   99                 {
  100                         struct ncp_fs_info info;
  101 
  102                         if ((permission(inode, MAY_WRITE) != 0)
  103                             && (current->uid != server->m.mounted_uid)) {
  104                                 return -EACCES;
  105                         }
  106                         if (copy_from_user(&info, (struct ncp_fs_info *) arg, 
  107                                 sizeof(info)))
  108                                 return -EFAULT;
  109 
  110                         if (info.version != NCP_GET_FS_INFO_VERSION) {
  111                                 DPRINTK("info.version invalid: %d\n", info.version);
  112                                 return -EINVAL;
  113                         }
  114                         /* TODO: info.addr = server->m.serv_addr; */
  115                         info.mounted_uid        = NEW_TO_OLD_UID(server->m.mounted_uid);
  116                         info.connection         = server->connection;
  117                         info.buffer_size        = server->buffer_size;
  118                         info.volume_number      = NCP_FINFO(inode)->volNumber;
  119                         info.directory_id       = NCP_FINFO(inode)->DosDirNum;
  120 
  121                         if (copy_to_user((struct ncp_fs_info *) arg, &info, 
  122                                 sizeof(info))) return -EFAULT;
  123                         return 0;
  124                 }
  125 
  126         case NCP_IOC_GET_FS_INFO_V2:
  127                 {
  128                         struct ncp_fs_info_v2 info2;
  129 
  130                         if ((permission(inode, MAY_WRITE) != 0)
  131                             && (current->uid != server->m.mounted_uid)) {
  132                                 return -EACCES;
  133                         }
  134                         if (copy_from_user(&info2, (struct ncp_fs_info_v2 *) arg, 
  135                                 sizeof(info2)))
  136                                 return -EFAULT;
  137 
  138                         if (info2.version != NCP_GET_FS_INFO_VERSION_V2) {
  139                                 DPRINTK("info.version invalid: %d\n", info2.version);
  140                                 return -EINVAL;
  141                         }
  142                         info2.mounted_uid   = server->m.mounted_uid;
  143                         info2.connection    = server->connection;
  144                         info2.buffer_size   = server->buffer_size;
  145                         info2.volume_number = NCP_FINFO(inode)->volNumber;
  146                         info2.directory_id  = NCP_FINFO(inode)->DosDirNum;
  147                         info2.dummy1 = info2.dummy2 = info2.dummy3 = 0;
  148 
  149                         if (copy_to_user((struct ncp_fs_info_v2 *) arg, &info2, 
  150                                 sizeof(info2))) return -EFAULT;
  151                         return 0;
  152                 }
  153 
  154         case NCP_IOC_GETMOUNTUID2:
  155                 {
  156                         unsigned long tmp = server->m.mounted_uid;
  157 
  158                         if (   (permission(inode, MAY_READ) != 0)
  159                             && (current->uid != server->m.mounted_uid))
  160                         {
  161                                 return -EACCES;
  162                         }
  163                         if (put_user(tmp, (unsigned long*) arg)) 
  164                                 return -EFAULT;
  165                         return 0;
  166                 }
  167 
  168         case NCP_IOC_GETROOT:
  169                 {
  170                         struct ncp_setroot_ioctl sr;
  171 
  172                         if (   (permission(inode, MAY_READ) != 0)
  173                             && (current->uid != server->m.mounted_uid))
  174                         {
  175                                 return -EACCES;
  176                         }
  177                         if (server->m.mounted_vol[0]) {
  178                                 struct dentry* dentry = inode->i_sb->s_root;
  179 
  180                                 if (dentry) {
  181                                         struct inode* inode = dentry->d_inode;
  182                                 
  183                                         if (inode) {
  184                                                 sr.volNumber = NCP_FINFO(inode)->volNumber;
  185                                                 sr.dirEntNum = NCP_FINFO(inode)->dirEntNum;
  186                                                 sr.namespace = server->name_space[sr.volNumber];
  187                                         } else
  188                                                 DPRINTK("ncpfs: s_root->d_inode==NULL\n");
  189                                 } else
  190                                         DPRINTK("ncpfs: s_root==NULL\n");
  191                         } else {
  192                                 sr.volNumber = -1;
  193                                 sr.namespace = 0;
  194                                 sr.dirEntNum = 0;
  195                         }
  196                         if (copy_to_user((struct ncp_setroot_ioctl*)arg, 
  197                                           &sr, 
  198                                           sizeof(sr))) return -EFAULT;
  199                         return 0;
  200                 }
  201         case NCP_IOC_SETROOT:
  202                 {
  203                         struct ncp_setroot_ioctl sr;
  204                         struct nw_info_struct i;
  205                         struct dentry* dentry;
  206 
  207                         if (!capable(CAP_SYS_ADMIN))
  208                         {
  209                                 return -EACCES;
  210                         }
  211                         if (server->root_setuped) return -EBUSY;
  212                         if (copy_from_user(&sr,
  213                                            (struct ncp_setroot_ioctl*)arg, 
  214                                            sizeof(sr))) return -EFAULT;
  215                         if (sr.volNumber < 0) {
  216                                 server->m.mounted_vol[0] = 0;
  217                                 i.volNumber = NCP_NUMBER_OF_VOLUMES + 1;
  218                                 i.dirEntNum = 0;
  219                                 i.DosDirNum = 0;
  220                         } else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) {
  221                                 return -EINVAL;
  222                         } else
  223                                 if (ncp_mount_subdir(server, &i, sr.volNumber,
  224                                                 sr.namespace, sr.dirEntNum))
  225                                         return -ENOENT;
  226 
  227                         dentry = inode->i_sb->s_root;
  228                         server->root_setuped = 1;
  229                         if (dentry) {
  230                                 struct inode* inode = dentry->d_inode;
  231                                 
  232                                 if (inode) {
  233                                         NCP_FINFO(inode)->volNumber = i.volNumber;
  234                                         NCP_FINFO(inode)->dirEntNum = i.dirEntNum;
  235                                         NCP_FINFO(inode)->DosDirNum = i.DosDirNum;
  236                                 } else
  237                                         DPRINTK("ncpfs: s_root->d_inode==NULL\n");
  238                         } else
  239                                 DPRINTK("ncpfs: s_root==NULL\n");
  240 
  241                         return 0;
  242                 }
  243 
  244 #ifdef CONFIG_NCPFS_PACKET_SIGNING      
  245         case NCP_IOC_SIGN_INIT:
  246                 if ((permission(inode, MAY_WRITE) != 0)
  247                     && (current->uid != server->m.mounted_uid))
  248                 {
  249                         return -EACCES;
  250                 }
  251                 if (arg) {
  252                         if (server->sign_wanted)
  253                         {
  254                                 struct ncp_sign_init sign;
  255 
  256                                 if (copy_from_user(&sign, (struct ncp_sign_init *) arg,
  257                                       sizeof(sign))) return -EFAULT;
  258                                 memcpy(server->sign_root,sign.sign_root,8);
  259                                 memcpy(server->sign_last,sign.sign_last,16);
  260                                 server->sign_active = 1;
  261                         }
  262                         /* ignore when signatures not wanted */
  263                 } else {
  264                         server->sign_active = 0;
  265                 }
  266                 return 0;               
  267                 
  268         case NCP_IOC_SIGN_WANTED:
  269                 if (   (permission(inode, MAY_READ) != 0)
  270                     && (current->uid != server->m.mounted_uid))
  271                 {
  272                         return -EACCES;
  273                 }
  274                 
  275                 if (put_user(server->sign_wanted, (int*) arg))
  276                         return -EFAULT;
  277                 return 0;
  278         case NCP_IOC_SET_SIGN_WANTED:
  279                 {
  280                         int newstate;
  281 
  282                         if (   (permission(inode, MAY_WRITE) != 0)
  283                             && (current->uid != server->m.mounted_uid))
  284                         {
  285                                 return -EACCES;
  286                         }
  287                         /* get only low 8 bits... */
  288                         if (get_user(newstate, (unsigned char *) arg))
  289                                 return -EFAULT;
  290                         if (server->sign_active) {
  291                                 /* cannot turn signatures OFF when active */
  292                                 if (!newstate) return -EINVAL;
  293                         } else {
  294                                 server->sign_wanted = newstate != 0;
  295                         }
  296                         return 0;
  297                 }
  298 
  299 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
  300 
  301 #ifdef CONFIG_NCPFS_IOCTL_LOCKING
  302         case NCP_IOC_LOCKUNLOCK:
  303                 if (   (permission(inode, MAY_WRITE) != 0)
  304                     && (current->uid != server->m.mounted_uid))
  305                 {
  306                         return -EACCES;
  307                 }
  308                 {
  309                         struct ncp_lock_ioctl    rqdata;
  310                         int result;
  311 
  312                         if (copy_from_user(&rqdata, (struct ncp_lock_ioctl*)arg,
  313                                 sizeof(rqdata))) return -EFAULT;
  314                         if (rqdata.origin != 0)
  315                                 return -EINVAL;
  316                         /* check for cmd */
  317                         switch (rqdata.cmd) {
  318                                 case NCP_LOCK_EX:
  319                                 case NCP_LOCK_SH:
  320                                                 if (rqdata.timeout == 0)
  321                                                         rqdata.timeout = NCP_LOCK_DEFAULT_TIMEOUT;
  322                                                 else if (rqdata.timeout > NCP_LOCK_MAX_TIMEOUT)
  323                                                         rqdata.timeout = NCP_LOCK_MAX_TIMEOUT;
  324                                                 break;
  325                                 case NCP_LOCK_LOG:
  326                                                 rqdata.timeout = NCP_LOCK_DEFAULT_TIMEOUT;      /* has no effect */
  327                                 case NCP_LOCK_CLEAR:
  328                                                 break;
  329                                 default:
  330                                                 return -EINVAL;
  331                         }
  332                         /* locking needs both read and write access */
  333                         if ((result = ncp_make_open(inode, O_RDWR)) != 0)
  334                         {
  335                                 return result;
  336                         }
  337                         result = -EIO;
  338                         if (!ncp_conn_valid(server))
  339                                 goto outrel;
  340                         result = -EISDIR;
  341                         if (!S_ISREG(inode->i_mode))
  342                                 goto outrel;
  343                         if (rqdata.cmd == NCP_LOCK_CLEAR)
  344                         {
  345                                 result = ncp_ClearPhysicalRecord(NCP_SERVER(inode),
  346                                                         NCP_FINFO(inode)->file_handle, 
  347                                                         rqdata.offset,
  348                                                         rqdata.length);
  349                                 if (result > 0) result = 0;     /* no such lock */
  350                         }
  351                         else
  352                         {
  353                                 int lockcmd;
  354 
  355                                 switch (rqdata.cmd)
  356                                 {
  357                                         case NCP_LOCK_EX:  lockcmd=1; break;
  358                                         case NCP_LOCK_SH:  lockcmd=3; break;
  359                                         default:           lockcmd=0; break;
  360                                 }
  361                                 result = ncp_LogPhysicalRecord(NCP_SERVER(inode),
  362                                                         NCP_FINFO(inode)->file_handle,
  363                                                         lockcmd,
  364                                                         rqdata.offset,
  365                                                         rqdata.length,
  366                                                         rqdata.timeout);
  367                                 if (result > 0) result = -EAGAIN;
  368                         }
  369 outrel:                 
  370                         ncp_inode_close(inode);
  371                         return result;
  372                 }
  373 #endif  /* CONFIG_NCPFS_IOCTL_LOCKING */
  374 
  375         case NCP_IOC_GETOBJECTNAME:
  376                 if (current->uid != server->m.mounted_uid) {
  377                         return -EACCES;
  378                 }
  379                 {
  380                         struct ncp_objectname_ioctl user;
  381                         size_t outl;
  382 
  383                         if (copy_from_user(&user, 
  384                                            (struct ncp_objectname_ioctl*)arg,
  385                                            sizeof(user))) return -EFAULT;
  386                         user.auth_type = server->auth.auth_type;
  387                         outl = user.object_name_len;
  388                         user.object_name_len = server->auth.object_name_len;
  389                         if (outl > user.object_name_len)
  390                                 outl = user.object_name_len;
  391                         if (outl) {
  392                                 if (copy_to_user(user.object_name,
  393                                                  server->auth.object_name,
  394                                                  outl)) return -EFAULT;
  395                         }
  396                         if (copy_to_user((struct ncp_objectname_ioctl*)arg,
  397                                          &user,
  398                                          sizeof(user))) return -EFAULT;
  399                         return 0;
  400                 }
  401         case NCP_IOC_SETOBJECTNAME:
  402                 if (current->uid != server->m.mounted_uid) {
  403                         return -EACCES;
  404                 }
  405                 {
  406                         struct ncp_objectname_ioctl user;
  407                         void* newname;
  408                         void* oldname;
  409                         size_t oldnamelen;
  410                         void* oldprivate;
  411                         size_t oldprivatelen;
  412 
  413                         if (copy_from_user(&user, 
  414                                            (struct ncp_objectname_ioctl*)arg,
  415                                            sizeof(user))) return -EFAULT;
  416                         if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN)
  417                                 return -ENOMEM;
  418                         if (user.object_name_len) {
  419                                 newname = ncp_kmalloc(user.object_name_len, GFP_USER);
  420                                 if (!newname) return -ENOMEM;
  421                                 if (copy_from_user(newname, user.object_name, user.object_name_len)) {
  422                                         ncp_kfree_s(newname, user.object_name_len);
  423                                         return -EFAULT;
  424                                 }
  425                         } else {
  426                                 newname = NULL;
  427                         }
  428                         /* enter critical section */
  429                         /* maybe that kfree can sleep so do that this way */
  430                         /* it is at least more SMP friendly (in future...) */
  431                         oldname = server->auth.object_name;
  432                         oldnamelen = server->auth.object_name_len;
  433                         oldprivate = server->priv.data;
  434                         oldprivatelen = server->priv.len;
  435                         server->auth.auth_type = user.auth_type;
  436                         server->auth.object_name_len = user.object_name_len;
  437                         server->auth.object_name = newname;
  438                         server->priv.len = 0;
  439                         server->priv.data = NULL;
  440                         /* leave critical section */
  441                         if (oldprivate) ncp_kfree_s(oldprivate, oldprivatelen);
  442                         if (oldname) ncp_kfree_s(oldname, oldnamelen);
  443                         return 0;
  444                 }
  445         case NCP_IOC_GETPRIVATEDATA:
  446                 if (current->uid != server->m.mounted_uid) {
  447                         return -EACCES;
  448                 }
  449                 {
  450                         struct ncp_privatedata_ioctl user;
  451                         size_t outl;
  452 
  453                         if (copy_from_user(&user, 
  454                                            (struct ncp_privatedata_ioctl*)arg,
  455                                            sizeof(user))) return -EFAULT;
  456                         outl = user.len;
  457                         user.len = server->priv.len;
  458                         if (outl > user.len) outl = user.len;
  459                         if (outl) {
  460                                 if (copy_to_user(user.data,
  461                                                  server->priv.data,
  462                                                  outl)) return -EFAULT;
  463                         }
  464                         if (copy_to_user((struct ncp_privatedata_ioctl*)arg,
  465                                          &user,
  466                                          sizeof(user))) return -EFAULT;
  467                         return 0;
  468                 }
  469         case NCP_IOC_SETPRIVATEDATA:
  470                 if (current->uid != server->m.mounted_uid) {
  471                         return -EACCES;
  472                 }
  473                 {
  474                         struct ncp_privatedata_ioctl user;
  475                         void* new;
  476                         void* old;
  477                         size_t oldlen;
  478 
  479                         if (copy_from_user(&user, 
  480                                            (struct ncp_privatedata_ioctl*)arg,
  481                                            sizeof(user))) return -EFAULT;
  482                         if (user.len > NCP_PRIVATE_DATA_MAX_LEN)
  483                                 return -ENOMEM;
  484                         if (user.len) {
  485                                 new = ncp_kmalloc(user.len, GFP_USER);
  486                                 if (!new) return -ENOMEM;
  487                                 if (copy_from_user(new, user.data, user.len)) {
  488                                         ncp_kfree_s(new, user.len);
  489                                         return -EFAULT;
  490                                 }
  491                         } else {
  492                                 new = NULL;
  493                         }
  494                         /* enter critical section */
  495                         old = server->priv.data;
  496                         oldlen = server->priv.len;
  497                         server->priv.len = user.len;
  498                         server->priv.data = new;
  499                         /* leave critical section */
  500                         if (old) ncp_kfree_s(old, oldlen);
  501                         return 0;
  502                 }
  503 
  504 #ifdef CONFIG_NCPFS_NLS
  505 /* Here we are select the iocharset and the codepage for NLS.
  506  * Thanks Petr Vandrovec for idea and many hints.
  507  */
  508         case NCP_IOC_SETCHARSETS:
  509                 if (!capable(CAP_SYS_ADMIN))
  510                         return -EACCES;
  511                 if (server->root_setuped)
  512                         return -EBUSY;
  513 
  514                 {
  515                         struct ncp_nls_ioctl user;
  516                         struct nls_table *codepage;
  517                         struct nls_table *iocharset;
  518                         struct nls_table *oldset_io;
  519                         struct nls_table *oldset_cp;
  520                         
  521                         if (copy_from_user(&user, (struct ncp_nls_ioctl*)arg,
  522                                         sizeof(user)))
  523                                 return -EFAULT;
  524 
  525                         codepage = NULL;
  526                         user.codepage[NCP_IOCSNAME_LEN] = 0;
  527                         if (!user.codepage[0] ||
  528                                         !strcmp(user.codepage, "default"))
  529                                 codepage = load_nls_default();
  530                         else {
  531                                 codepage = load_nls(user.codepage);
  532                                 if (!codepage) {
  533                                         return -EBADRQC;
  534                                 }
  535                         }
  536 
  537                         iocharset = NULL;
  538                         user.iocharset[NCP_IOCSNAME_LEN] = 0;
  539                         if (!user.iocharset[0] ||
  540                                         !strcmp(user.iocharset, "default")) {
  541                                 iocharset = load_nls_default();
  542                                 NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
  543                         } else {
  544                                 if (!strcmp(user.iocharset, "utf8")) {
  545                                         iocharset = load_nls_default();
  546                                         NCP_SET_FLAG(server, NCP_FLAG_UTF8);
  547                                 } else {
  548                                         iocharset = load_nls(user.iocharset);
  549                                         if (!iocharset) {
  550                                                 unload_nls(codepage);
  551                                                 return -EBADRQC;
  552                                         }
  553                                         NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
  554                                 }
  555                         }
  556 
  557                         oldset_cp = server->nls_vol;
  558                         server->nls_vol = codepage;
  559                         oldset_io = server->nls_io;
  560                         server->nls_io = iocharset;
  561 
  562                         if (oldset_cp)
  563                                 unload_nls(oldset_cp);
  564                         if (oldset_io)
  565                                 unload_nls(oldset_io);
  566 
  567                         return 0;
  568                 }
  569                 
  570         case NCP_IOC_GETCHARSETS: /* not tested */
  571                 {
  572                         struct ncp_nls_ioctl user;
  573                         int len;
  574 
  575                         memset(&user, 0, sizeof(user));
  576                         if (server->nls_vol && server->nls_vol->charset) {
  577                                 len = strlen(server->nls_vol->charset);
  578                                 if (len > NCP_IOCSNAME_LEN)
  579                                         len = NCP_IOCSNAME_LEN;
  580                                 strncpy(user.codepage,
  581                                                 server->nls_vol->charset, len);
  582                                 user.codepage[len] = 0;
  583                         }
  584 
  585                         if (NCP_IS_FLAG(server, NCP_FLAG_UTF8))
  586                                 strcpy(user.iocharset, "utf8");
  587                         else
  588                                 if (server->nls_io && server->nls_io->charset) {
  589                                         len = strlen(server->nls_io->charset);
  590                                         if (len > NCP_IOCSNAME_LEN)
  591                                                 len = NCP_IOCSNAME_LEN;
  592                                         strncpy(user.iocharset,
  593                                                 server->nls_io->charset, len);
  594                                         user.iocharset[len] = 0;
  595                                 }
  596 
  597                         if (copy_to_user((struct ncp_nls_ioctl*)arg, &user,
  598                                         sizeof(user)))
  599                                 return -EFAULT;
  600 
  601                         return 0;
  602                 }
  603 #endif /* CONFIG_NCPFS_NLS */
  604         case NCP_IOC_SETDENTRYTTL:
  605                 if ((permission(inode, MAY_WRITE) != 0) &&
  606                                  (current->uid != server->m.mounted_uid))
  607                         return -EACCES;
  608                 {
  609                         u_int32_t user;
  610 
  611                         if (copy_from_user(&user, (u_int32_t*)arg, sizeof(user)))
  612                                 return -EFAULT;
  613                         /* 20 secs at most... */
  614                         if (user > 20000)
  615                                 return -EINVAL;
  616                         user = (user * HZ) / 1000;
  617                         server->dentry_ttl = user;
  618                         return 0;
  619                 }
  620                 
  621         case NCP_IOC_GETDENTRYTTL:
  622                 {
  623                         u_int32_t user = (server->dentry_ttl * 1000) / HZ;
  624                         if (copy_to_user((u_int32_t*)arg, &user, sizeof(user)))
  625                                 return -EFAULT;
  626                         return 0;
  627                 }
  628 
  629         }
  630 /* #ifdef CONFIG_UID16 */
  631         /* NCP_IOC_GETMOUNTUID may be same as NCP_IOC_GETMOUNTUID2,
  632            so we have this out of switch */
  633         if (cmd == NCP_IOC_GETMOUNTUID) {
  634                 if ((permission(inode, MAY_READ) != 0)
  635                     && (current->uid != server->m.mounted_uid)) {
  636                         return -EACCES;
  637                 }
  638                 if (put_user(NEW_TO_OLD_UID(server->m.mounted_uid), (__kernel_uid_t *) arg))
  639                         return -EFAULT;
  640                 return 0;
  641         }
  642 /* #endif */
  643         return -EINVAL;
  644 }

Cache object: 738f13e362f3a9d168902a84b2012ba5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.