root/source4/ntvfs/unixuid/vfs_unixuid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. save_unix_security
  2. set_unix_security
  3. nt_token_to_unix_security
  4. unixuid_setup_security
  5. unixuid_connect
  6. unixuid_disconnect
  7. unixuid_unlink
  8. unixuid_ioctl
  9. unixuid_chkpath
  10. unixuid_qpathinfo
  11. unixuid_qfileinfo
  12. unixuid_setpathinfo
  13. unixuid_open
  14. unixuid_mkdir
  15. unixuid_rmdir
  16. unixuid_rename
  17. unixuid_copy
  18. unixuid_read
  19. unixuid_write
  20. unixuid_seek
  21. unixuid_flush
  22. unixuid_close
  23. unixuid_exit
  24. unixuid_logoff
  25. unixuid_async_setup
  26. unixuid_cancel
  27. unixuid_notify
  28. unixuid_lock
  29. unixuid_setfileinfo
  30. unixuid_fsinfo
  31. unixuid_lpq
  32. unixuid_search_first
  33. unixuid_search_next
  34. unixuid_search_close
  35. unixuid_trans
  36. ntvfs_unixuid_init

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    a pass-thru NTVFS module to setup a security context using unix
   5    uid/gid
   6 
   7    Copyright (C) Andrew Tridgell 2004
   8 
   9    This program is free software; you can redistribute it and/or modify
  10    it under the terms of the GNU General Public License as published by
  11    the Free Software Foundation; either version 3 of the License, or
  12    (at your option) any later version.
  13    
  14    This program is distributed in the hope that it will be useful,
  15    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17    GNU General Public License for more details.
  18    
  19    You should have received a copy of the GNU General Public License
  20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  21 */
  22 
  23 #include "includes.h"
  24 #include "system/filesys.h"
  25 #include "system/passwd.h"
  26 #include "auth/auth.h"
  27 #include "ntvfs/ntvfs.h"
  28 #include "libcli/wbclient/wbclient.h"
  29 
  30 struct unixuid_private {
  31         struct wbc_context *wbc_ctx;
  32         struct unix_sec_ctx *last_sec_ctx;
  33         struct security_token *last_token;
  34 };
  35 
  36 
  37 
  38 struct unix_sec_ctx {
  39         uid_t uid;
  40         gid_t gid;
  41         uint_t ngroups;
  42         gid_t *groups;
  43 };
  44 
  45 /*
  46   pull the current security context into a unix_sec_ctx
  47 */
  48 static struct unix_sec_ctx *save_unix_security(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  49 {
  50         struct unix_sec_ctx *sec = talloc(mem_ctx, struct unix_sec_ctx);
  51         if (sec == NULL) {
  52                 return NULL;
  53         }
  54         sec->uid = geteuid();
  55         sec->gid = getegid();
  56         sec->ngroups = getgroups(0, NULL);
  57         if (sec->ngroups == -1) {
  58                 talloc_free(sec);
  59                 return NULL;
  60         }
  61         sec->groups = talloc_array(sec, gid_t, sec->ngroups);
  62         if (sec->groups == NULL) {
  63                 talloc_free(sec);
  64                 return NULL;
  65         }
  66 
  67         if (getgroups(sec->ngroups, sec->groups) != sec->ngroups) {
  68                 talloc_free(sec);
  69                 return NULL;
  70         }
  71 
  72         return sec;
  73 }
  74 
  75 /*
  76   set the current security context from a unix_sec_ctx
  77 */
  78 static NTSTATUS set_unix_security(struct unix_sec_ctx *sec)
     /* [<][>][^][v][top][bottom][index][help] */
  79 {
  80         seteuid(0);
  81 
  82         if (setgroups(sec->ngroups, sec->groups) != 0) {
  83                 return NT_STATUS_ACCESS_DENIED;
  84         }
  85         if (setegid(sec->gid) != 0) {
  86                 return NT_STATUS_ACCESS_DENIED;
  87         }
  88         if (seteuid(sec->uid) != 0) {
  89                 return NT_STATUS_ACCESS_DENIED;
  90         }
  91         return NT_STATUS_OK;
  92 }
  93 
  94 /*
  95   form a unix_sec_ctx from the current security_token
  96 */
  97 static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
  98                                           struct ntvfs_request *req,
  99                                           struct security_token *token,
 100                                           struct unix_sec_ctx **sec)
 101 {
 102         struct unixuid_private *priv = ntvfs->private_data;
 103         int i;
 104         NTSTATUS status;
 105         struct id_mapping *ids;
 106         struct composite_context *ctx;
 107         *sec = talloc(req, struct unix_sec_ctx);
 108 
 109         /* we can't do unix security without a user and group */
 110         if (token->num_sids < 2) {
 111                 return NT_STATUS_ACCESS_DENIED;
 112         }
 113 
 114         ids = talloc_array(req, struct id_mapping, token->num_sids);
 115         NT_STATUS_HAVE_NO_MEMORY(ids);
 116 
 117         ids[0].unixid = NULL;
 118         ids[0].sid = token->user_sid;
 119         ids[0].status = NT_STATUS_NONE_MAPPED;
 120 
 121         ids[1].unixid = NULL;
 122         ids[1].sid = token->group_sid;
 123         ids[1].status = NT_STATUS_NONE_MAPPED;
 124 
 125         (*sec)->ngroups = token->num_sids - 2;
 126         (*sec)->groups = talloc_array(*sec, gid_t, (*sec)->ngroups);
 127         NT_STATUS_HAVE_NO_MEMORY((*sec)->groups);
 128 
 129         for (i=0;i<(*sec)->ngroups;i++) {
 130                 ids[i+2].unixid = NULL;
 131                 ids[i+2].sid = token->sids[i+2];
 132                 ids[i+2].status = NT_STATUS_NONE_MAPPED;
 133         }
 134 
 135         ctx = wbc_sids_to_xids_send(priv->wbc_ctx, ids, token->num_sids, ids);
 136         NT_STATUS_HAVE_NO_MEMORY(ctx);
 137 
 138         status = wbc_sids_to_xids_recv(ctx, &ids);
 139         NT_STATUS_NOT_OK_RETURN(status);
 140 
 141         if (ids[0].unixid->type == ID_TYPE_BOTH ||
 142             ids[0].unixid->type == ID_TYPE_UID) {
 143                 (*sec)->uid = ids[0].unixid->id;
 144         } else {
 145                 return NT_STATUS_INVALID_SID;
 146         }
 147 
 148         if (ids[1].unixid->type == ID_TYPE_BOTH ||
 149             ids[1].unixid->type == ID_TYPE_GID) {
 150                 (*sec)->gid = ids[1].unixid->id;
 151         } else {
 152                 return NT_STATUS_INVALID_SID;
 153         }
 154 
 155         for (i=0;i<(*sec)->ngroups;i++) {
 156                 if (ids[i+2].unixid->type == ID_TYPE_BOTH ||
 157                     ids[i+2].unixid->type == ID_TYPE_GID) {
 158                         (*sec)->groups[i] = ids[i+2].unixid->id;
 159                 } else {
 160                         return NT_STATUS_INVALID_SID;
 161                 }
 162         }
 163 
 164         return NT_STATUS_OK;
 165 }
 166 
 167 /*
 168   setup our unix security context according to the session authentication info
 169 */
 170 static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 171                                        struct ntvfs_request *req, struct unix_sec_ctx **sec)
 172 {
 173         struct unixuid_private *priv = ntvfs->private_data;
 174         struct security_token *token;
 175         struct unix_sec_ctx *newsec;
 176         NTSTATUS status;
 177 
 178         if (req->session_info == NULL) {
 179                 return NT_STATUS_ACCESS_DENIED;
 180         }
 181 
 182         token = req->session_info->security_token;
 183 
 184         *sec = save_unix_security(ntvfs);
 185         if (*sec == NULL) {
 186                 return NT_STATUS_NO_MEMORY;
 187         }
 188 
 189         if (token == priv->last_token) {
 190                 newsec = priv->last_sec_ctx;
 191         } else {
 192                 status = nt_token_to_unix_security(ntvfs, req, token, &newsec);
 193                 if (!NT_STATUS_IS_OK(status)) {
 194                         talloc_free(*sec);
 195                         return status;
 196                 }
 197                 if (priv->last_sec_ctx) {
 198                         talloc_free(priv->last_sec_ctx);
 199                 }
 200                 priv->last_sec_ctx = newsec;
 201                 priv->last_token = token;
 202                 talloc_steal(priv, newsec);
 203         }
 204 
 205         status = set_unix_security(newsec);
 206         if (!NT_STATUS_IS_OK(status)) {
 207                 talloc_free(*sec);
 208                 return status;
 209         }
 210 
 211         return NT_STATUS_OK;
 212 }
 213 
 214 /*
 215   this pass through macro operates on request contexts
 216 */
 217 #define PASS_THRU_REQ(ntvfs, req, op, args) do { \
 218         NTSTATUS status2; \
 219         struct unix_sec_ctx *sec; \
 220         status = unixuid_setup_security(ntvfs, req, &sec); \
 221         NT_STATUS_NOT_OK_RETURN(status); \
 222         status = ntvfs_next_##op args; \
 223         status2 = set_unix_security(sec); \
 224         talloc_free(sec); \
 225         if (!NT_STATUS_IS_OK(status2)) smb_panic("Unable to reset security context"); \
 226 } while (0)
 227 
 228 
 229 
 230 /*
 231   connect to a share - used when a tree_connect operation comes in.
 232 */
 233 static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 234                                 struct ntvfs_request *req, const char *sharename)
 235 {
 236         struct unixuid_private *priv;
 237         NTSTATUS status;
 238 
 239         priv = talloc(ntvfs, struct unixuid_private);
 240         if (!priv) {
 241                 return NT_STATUS_NO_MEMORY;
 242         }
 243 
 244         priv->wbc_ctx = wbc_init(priv, ntvfs->ctx->msg_ctx,
 245                                     ntvfs->ctx->event_ctx);
 246         if (priv->wbc_ctx == NULL) {
 247                 talloc_free(priv);
 248                 return NT_STATUS_INTERNAL_ERROR;
 249         }
 250 
 251         ntvfs->private_data = priv;
 252         priv->last_sec_ctx = NULL;
 253         priv->last_token = NULL;
 254 
 255         /* we don't use PASS_THRU_REQ here, as the connect operation runs with 
 256            root privileges. This allows the backends to setup any database
 257            links they might need during the connect. */
 258         status = ntvfs_next_connect(ntvfs, req, sharename);
 259 
 260         return status;
 261 }
 262 
 263 /*
 264   disconnect from a share
 265 */
 266 static NTSTATUS unixuid_disconnect(struct ntvfs_module_context *ntvfs)
     /* [<][>][^][v][top][bottom][index][help] */
 267 {
 268         struct unixuid_private *priv = ntvfs->private_data;
 269         NTSTATUS status;
 270 
 271         talloc_free(priv);
 272         ntvfs->private_data = NULL;
 273 
 274         status = ntvfs_next_disconnect(ntvfs);
 275  
 276         return status;
 277 }
 278 
 279 
 280 /*
 281   delete a file
 282 */
 283 static NTSTATUS unixuid_unlink(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 284                               struct ntvfs_request *req,
 285                               union smb_unlink *unl)
 286 {
 287         NTSTATUS status;
 288 
 289         PASS_THRU_REQ(ntvfs, req, unlink, (ntvfs, req, unl));
 290 
 291         return status;
 292 }
 293 
 294 /*
 295   ioctl interface
 296 */
 297 static NTSTATUS unixuid_ioctl(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 298                              struct ntvfs_request *req, union smb_ioctl *io)
 299 {
 300         NTSTATUS status;
 301 
 302         PASS_THRU_REQ(ntvfs, req, ioctl, (ntvfs, req, io));
 303 
 304         return status;
 305 }
 306 
 307 /*
 308   check if a directory exists
 309 */
 310 static NTSTATUS unixuid_chkpath(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 311                                 struct ntvfs_request *req,
 312                                 union smb_chkpath *cp)
 313 {
 314         NTSTATUS status;
 315 
 316         PASS_THRU_REQ(ntvfs, req, chkpath, (ntvfs, req, cp));
 317 
 318         return status;
 319 }
 320 
 321 /*
 322   return info on a pathname
 323 */
 324 static NTSTATUS unixuid_qpathinfo(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 325                                  struct ntvfs_request *req, union smb_fileinfo *info)
 326 {
 327         NTSTATUS status;
 328 
 329         PASS_THRU_REQ(ntvfs, req, qpathinfo, (ntvfs, req, info));
 330 
 331         return status;
 332 }
 333 
 334 /*
 335   query info on a open file
 336 */
 337 static NTSTATUS unixuid_qfileinfo(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 338                                  struct ntvfs_request *req, union smb_fileinfo *info)
 339 {
 340         NTSTATUS status;
 341 
 342         PASS_THRU_REQ(ntvfs, req, qfileinfo, (ntvfs, req, info));
 343 
 344         return status;
 345 }
 346 
 347 
 348 /*
 349   set info on a pathname
 350 */
 351 static NTSTATUS unixuid_setpathinfo(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 352                                    struct ntvfs_request *req, union smb_setfileinfo *st)
 353 {
 354         NTSTATUS status;
 355 
 356         PASS_THRU_REQ(ntvfs, req, setpathinfo, (ntvfs, req, st));
 357 
 358         return status;
 359 }
 360 
 361 /*
 362   open a file
 363 */
 364 static NTSTATUS unixuid_open(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 365                              struct ntvfs_request *req, union smb_open *io)
 366 {
 367         NTSTATUS status;
 368 
 369         PASS_THRU_REQ(ntvfs, req, open, (ntvfs, req, io));
 370 
 371         return status;
 372 }
 373 
 374 /*
 375   create a directory
 376 */
 377 static NTSTATUS unixuid_mkdir(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 378                              struct ntvfs_request *req, union smb_mkdir *md)
 379 {
 380         NTSTATUS status;
 381 
 382         PASS_THRU_REQ(ntvfs, req, mkdir, (ntvfs, req, md));
 383 
 384         return status;
 385 }
 386 
 387 /*
 388   remove a directory
 389 */
 390 static NTSTATUS unixuid_rmdir(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 391                              struct ntvfs_request *req, struct smb_rmdir *rd)
 392 {
 393         NTSTATUS status;
 394 
 395         PASS_THRU_REQ(ntvfs, req, rmdir, (ntvfs, req, rd));
 396 
 397         return status;
 398 }
 399 
 400 /*
 401   rename a set of files
 402 */
 403 static NTSTATUS unixuid_rename(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 404                               struct ntvfs_request *req, union smb_rename *ren)
 405 {
 406         NTSTATUS status;
 407 
 408         PASS_THRU_REQ(ntvfs, req, rename, (ntvfs, req, ren));
 409 
 410         return status;
 411 }
 412 
 413 /*
 414   copy a set of files
 415 */
 416 static NTSTATUS unixuid_copy(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 417                             struct ntvfs_request *req, struct smb_copy *cp)
 418 {
 419         NTSTATUS status;
 420 
 421         PASS_THRU_REQ(ntvfs, req, copy, (ntvfs, req, cp));
 422 
 423         return status;
 424 }
 425 
 426 /*
 427   read from a file
 428 */
 429 static NTSTATUS unixuid_read(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 430                             struct ntvfs_request *req, union smb_read *rd)
 431 {
 432         NTSTATUS status;
 433 
 434         PASS_THRU_REQ(ntvfs, req, read, (ntvfs, req, rd));
 435 
 436         return status;
 437 }
 438 
 439 /*
 440   write to a file
 441 */
 442 static NTSTATUS unixuid_write(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 443                              struct ntvfs_request *req, union smb_write *wr)
 444 {
 445         NTSTATUS status;
 446 
 447         PASS_THRU_REQ(ntvfs, req, write, (ntvfs, req, wr));
 448 
 449         return status;
 450 }
 451 
 452 /*
 453   seek in a file
 454 */
 455 static NTSTATUS unixuid_seek(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 456                              struct ntvfs_request *req,
 457                              union smb_seek *io)
 458 {
 459         NTSTATUS status;
 460 
 461         PASS_THRU_REQ(ntvfs, req, seek, (ntvfs, req, io));
 462 
 463         return status;
 464 }
 465 
 466 /*
 467   flush a file
 468 */
 469 static NTSTATUS unixuid_flush(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 470                               struct ntvfs_request *req,
 471                               union smb_flush *io)
 472 {
 473         NTSTATUS status;
 474 
 475         PASS_THRU_REQ(ntvfs, req, flush, (ntvfs, req, io));
 476 
 477         return status;
 478 }
 479 
 480 /*
 481   close a file
 482 */
 483 static NTSTATUS unixuid_close(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 484                              struct ntvfs_request *req, union smb_close *io)
 485 {
 486         NTSTATUS status;
 487 
 488         PASS_THRU_REQ(ntvfs, req, close, (ntvfs, req, io));
 489 
 490         return status;
 491 }
 492 
 493 /*
 494   exit - closing files
 495 */
 496 static NTSTATUS unixuid_exit(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 497                             struct ntvfs_request *req)
 498 {
 499         NTSTATUS status;
 500 
 501         PASS_THRU_REQ(ntvfs, req, exit, (ntvfs, req));
 502 
 503         return status;
 504 }
 505 
 506 /*
 507   logoff - closing files
 508 */
 509 static NTSTATUS unixuid_logoff(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 510                               struct ntvfs_request *req)
 511 {
 512         struct unixuid_private *priv = ntvfs->private_data;
 513         NTSTATUS status;
 514 
 515         PASS_THRU_REQ(ntvfs, req, logoff, (ntvfs, req));
 516 
 517         priv->last_token = NULL;
 518 
 519         return status;
 520 }
 521 
 522 /*
 523   async setup
 524 */
 525 static NTSTATUS unixuid_async_setup(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 526                                     struct ntvfs_request *req, 
 527                                     void *private_data)
 528 {
 529         NTSTATUS status;
 530 
 531         PASS_THRU_REQ(ntvfs, req, async_setup, (ntvfs, req, private_data));
 532 
 533         return status;
 534 }
 535 
 536 /*
 537   cancel an async request
 538 */
 539 static NTSTATUS unixuid_cancel(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 540                                struct ntvfs_request *req)
 541 {
 542         NTSTATUS status;
 543 
 544         PASS_THRU_REQ(ntvfs, req, cancel, (ntvfs, req));
 545 
 546         return status;
 547 }
 548 
 549 /*
 550   change notify
 551 */
 552 static NTSTATUS unixuid_notify(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 553                                struct ntvfs_request *req, union smb_notify *info)
 554 {
 555         NTSTATUS status;
 556 
 557         PASS_THRU_REQ(ntvfs, req, notify, (ntvfs, req, info));
 558 
 559         return status;
 560 }
 561 
 562 /*
 563   lock a byte range
 564 */
 565 static NTSTATUS unixuid_lock(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 566                             struct ntvfs_request *req, union smb_lock *lck)
 567 {
 568         NTSTATUS status;
 569 
 570         PASS_THRU_REQ(ntvfs, req, lock, (ntvfs, req, lck));
 571 
 572         return status;
 573 }
 574 
 575 /*
 576   set info on a open file
 577 */
 578 static NTSTATUS unixuid_setfileinfo(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 579                                    struct ntvfs_request *req, 
 580                                    union smb_setfileinfo *info)
 581 {
 582         NTSTATUS status;
 583 
 584         PASS_THRU_REQ(ntvfs, req, setfileinfo, (ntvfs, req, info));
 585 
 586         return status;
 587 }
 588 
 589 
 590 /*
 591   return filesystem space info
 592 */
 593 static NTSTATUS unixuid_fsinfo(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 594                               struct ntvfs_request *req, union smb_fsinfo *fs)
 595 {
 596         NTSTATUS status;
 597 
 598         PASS_THRU_REQ(ntvfs, req, fsinfo, (ntvfs, req, fs));
 599 
 600         return status;
 601 }
 602 
 603 /*
 604   return print queue info
 605 */
 606 static NTSTATUS unixuid_lpq(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 607                            struct ntvfs_request *req, union smb_lpq *lpq)
 608 {
 609         NTSTATUS status;
 610 
 611         PASS_THRU_REQ(ntvfs, req, lpq, (ntvfs, req, lpq));
 612 
 613         return status;
 614 }
 615 
 616 /* 
 617    list files in a directory matching a wildcard pattern
 618 */
 619 static NTSTATUS unixuid_search_first(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 620                                     struct ntvfs_request *req, union smb_search_first *io, 
 621                                     void *search_private, 
 622                                     bool (*callback)(void *, const union smb_search_data *))
 623 {
 624         NTSTATUS status;
 625 
 626         PASS_THRU_REQ(ntvfs, req, search_first, (ntvfs, req, io, search_private, callback));
 627 
 628         return status;
 629 }
 630 
 631 /* continue a search */
 632 static NTSTATUS unixuid_search_next(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 633                                    struct ntvfs_request *req, union smb_search_next *io, 
 634                                    void *search_private, 
 635                                    bool (*callback)(void *, const union smb_search_data *))
 636 {
 637         NTSTATUS status;
 638 
 639         PASS_THRU_REQ(ntvfs, req, search_next, (ntvfs, req, io, search_private, callback));
 640 
 641         return status;
 642 }
 643 
 644 /* close a search */
 645 static NTSTATUS unixuid_search_close(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 646                                     struct ntvfs_request *req, union smb_search_close *io)
 647 {
 648         NTSTATUS status;
 649 
 650         PASS_THRU_REQ(ntvfs, req, search_close, (ntvfs, req, io));
 651 
 652         return status;
 653 }
 654 
 655 /* SMBtrans - not used on file shares */
 656 static NTSTATUS unixuid_trans(struct ntvfs_module_context *ntvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 657                              struct ntvfs_request *req, struct smb_trans2 *trans2)
 658 {
 659         NTSTATUS status;
 660 
 661         PASS_THRU_REQ(ntvfs, req, trans, (ntvfs, req, trans2));
 662 
 663         return status;
 664 }
 665 
 666 /*
 667   initialise the unixuid backend, registering ourselves with the ntvfs subsystem
 668  */
 669 NTSTATUS ntvfs_unixuid_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 670 {
 671         NTSTATUS ret;
 672         struct ntvfs_ops ops;
 673         NTVFS_CURRENT_CRITICAL_SIZES(vers);
 674 
 675         ZERO_STRUCT(ops);
 676 
 677         /* fill in all the operations */
 678         ops.connect = unixuid_connect;
 679         ops.disconnect = unixuid_disconnect;
 680         ops.unlink = unixuid_unlink;
 681         ops.chkpath = unixuid_chkpath;
 682         ops.qpathinfo = unixuid_qpathinfo;
 683         ops.setpathinfo = unixuid_setpathinfo;
 684         ops.open = unixuid_open;
 685         ops.mkdir = unixuid_mkdir;
 686         ops.rmdir = unixuid_rmdir;
 687         ops.rename = unixuid_rename;
 688         ops.copy = unixuid_copy;
 689         ops.ioctl = unixuid_ioctl;
 690         ops.read = unixuid_read;
 691         ops.write = unixuid_write;
 692         ops.seek = unixuid_seek;
 693         ops.flush = unixuid_flush;      
 694         ops.close = unixuid_close;
 695         ops.exit = unixuid_exit;
 696         ops.lock = unixuid_lock;
 697         ops.setfileinfo = unixuid_setfileinfo;
 698         ops.qfileinfo = unixuid_qfileinfo;
 699         ops.fsinfo = unixuid_fsinfo;
 700         ops.lpq = unixuid_lpq;
 701         ops.search_first = unixuid_search_first;
 702         ops.search_next = unixuid_search_next;
 703         ops.search_close = unixuid_search_close;
 704         ops.trans = unixuid_trans;
 705         ops.logoff = unixuid_logoff;
 706         ops.async_setup = unixuid_async_setup;
 707         ops.cancel = unixuid_cancel;
 708         ops.notify = unixuid_notify;
 709 
 710         ops.name = "unixuid";
 711 
 712         /* we register under all 3 backend types, as we are not type specific */
 713         ops.type = NTVFS_DISK;  
 714         ret = ntvfs_register(&ops, &vers);
 715         if (!NT_STATUS_IS_OK(ret)) goto failed;
 716 
 717         ops.type = NTVFS_PRINT; 
 718         ret = ntvfs_register(&ops, &vers);
 719         if (!NT_STATUS_IS_OK(ret)) goto failed;
 720 
 721         ops.type = NTVFS_IPC;   
 722         ret = ntvfs_register(&ops, &vers);
 723         if (!NT_STATUS_IS_OK(ret)) goto failed;
 724         
 725 failed:
 726         return ret;
 727 }

/* [<][>][^][v][top][bottom][index][help] */