home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / BWNFSD.TAR / bwnfsd / bwnfsd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-14  |  53.4 KB  |  2,107 lines

  1. /*
  2. VERSION  2.3
  3. MODIFIED 11/11/91
  4.  
  5.     BWNFSD is an RPC daemon used in conjunction with BWNFS ( a client NFS
  6. for DOS based PCs. BWNFSD provides Authentication, Print Spooling,
  7. DOS 3.1 Locking, DOS 3.1 Sharing, GID name mapping, UID name mapping services
  8. for BWNFS and associated applications on the PC. BWNFSD is being used also
  9. by Macintosh NFS clients.
  10.  
  11.     The BWNFSD code is originally copyright Beame & Whiteside Software Ltd.
  12. and now is released to the Public Domain. The intent is that all server vendors
  13. included a version of BWNFSD with their operating system. BWNFSD can run
  14. simultantiously as PCNFSD, but provides many more features.
  15.  
  16.     Please send modifications to:
  17.  
  18.         Beame & Whiteside Software Ltd.
  19.         P.O. Box 8130
  20.         Dundas, Ontario
  21.         Canada L9H 5E7
  22.         +1 (416) 765-0822
  23.  
  24.     Please modify by including "ifdefs" for your particular operating
  25. system, with appropriate modifications to the "makefile".
  26.  
  27. Modified 02/14/93, Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  28. to use #define macros for pathnames and such.  Much cleaner!
  29. */
  30. #include <stdio.h>
  31. #include <sys/types.h>
  32. #ifdef AIX
  33. #include <sys/select.h>
  34. #endif
  35. #include <sys/stat.h>
  36. #include <rpc/rpc.h>
  37. #include <sys/socket.h>
  38. #include <sys/param.h>
  39. #include <sys/time.h>
  40. #include <sys/ioctl.h>
  41. #include <ctype.h>
  42. #include <arpa/inet.h>
  43. #include <netdb.h>
  44. #include <pwd.h>
  45. #include <signal.h>
  46. #include <grp.h>
  47.  
  48. #ifdef SYSV32
  49. #   include <string.h>
  50. #else
  51. #   include <strings.h>
  52. #endif
  53.  
  54. #ifdef SHADOW
  55. #   include <shadow.h>
  56. #endif
  57.  
  58. #ifdef sgi
  59. extern struct group *getgrent();
  60. #endif
  61.  
  62. extern char *crypt();
  63.  
  64. extern char *strchr();
  65.  
  66. #ifdef WINNFS
  67. #   include <rpc/clnt.h>
  68. #   include <tiuser.h>
  69. #endif
  70.  
  71.  
  72. #define LP_ALLOW    "/usr/spool/lp/admins/lp/printers/%s/users.allow"
  73. #define LP_DENY        "/usr/spool/lp/admins/lp/printers/%s/users.deny"
  74. #define LP_FILE        "%s/%s.%03d"
  75. #ifdef SCO
  76. #   define P_STATUS    "/usr/spool/lp/system/pstatus"
  77. #   define C_STATUS    "/usr/spool/lp/system/cstatus"
  78. #   define LP_FILE1    "%s/%s.%03dq"
  79. #else
  80. #   define PRINTCAP    "/etc/printcap"
  81. #   define LP_FILE1    "%s/%s.%03dqueued"
  82. #endif
  83.  
  84.  
  85. #ifdef SCO
  86. #define ALLOW 0
  87. #define DENY  1
  88. #define CLASS 2
  89.  
  90. struct {
  91.         int access;
  92.         int count;
  93.         union {
  94.         char **users;
  95.         int  *printers;
  96.         } n;
  97.     } printer_access[100];
  98. #endif
  99.  
  100. #define BW_NFS_PROGRAM 0x2f00dbadL
  101. #define BW_NFS_VERSION 1L
  102.  
  103. #define SPOOL_INQUIRE  1L    /* Return fhandle of spool directory */
  104. #define SPOOL_FILE     2L    /* Spool file */
  105. #define AUTHORIZE      3L    /* Authorize and return UID and GIDs (max 16) */
  106. #define GRP_NAME_TO_NUMB 4L    /* Convert group name to number */
  107. #define GRP_TO_NUMBER 5L    /* Convert group number(s) to name(s) */
  108. #define RETURN_HOST    6L    /* Convert IP to hostname */
  109. #define UID_TO_NAME    7L    /* Convert UID(s) to name(s) */
  110. #define SHARE          20L    /* DOS 3.1 Share function */
  111. #define UNSHARE       21L    /* DOS 3.1 UnShare function */
  112. #define LOCK          22L    /* DOS 3.1 Lock request */
  113. #define REMOVE        23L    /* Remove all locks/shares for PC */
  114. #define UNLOCK        24L    /* DOS 3.1 Unlock request */
  115.  
  116. #define NUSRS  10        /* Maximum names to convert */
  117.  
  118. static  char     dir[32],g_string[32];
  119. static  char     spool_dir[132], file[256], file1[256];
  120. static  char    remote_host[16];
  121. static  char     *printers[500];
  122. static    int      num_printers;
  123. static    char      printer[12];
  124. static  char    *jobname;
  125. static  char      file_name[9];
  126. static  char    *hostname,*p;
  127. static  int       extension, lgids[NGRPS+1];
  128. static  int    luids[NUSRS+1];
  129. static  int    A_flag=0, s_flag=0, do_print;
  130. static  u_long    my_ip;
  131. static  u_long  incomming_ip;
  132. int debugmode;
  133.  
  134. static  struct mm_ips        /* Valid hosts to authenticate for */
  135.      {
  136.         char    type;
  137.         u_long    ip;
  138.         u_long    mask;
  139.         u_long    redirect_ip;
  140.     } **ips;
  141.  
  142. static struct mm_uids        /* Cache of uid to name translation */
  143.     {
  144.         int    mm_uid;
  145.         char    *mm_username;
  146.     } **uds;
  147.  
  148.  
  149. static struct mm_gidss        /* Cache of uid and associated gids */
  150.     {
  151.         int mm_uid;
  152.         int mm_gid;
  153.         int mm_gid_count;
  154.         int mm_gids[NGRPS];
  155.     } **gds;
  156.  
  157.  
  158. static int gids_count=0,uids_count=0;
  159.  
  160.  
  161. static int    ips_count=0;
  162.  
  163. static struct    locking
  164.     {
  165.         unsigned long   cookie;         /* 4 bytes */
  166.         char            name[17];       /* 16 character name */
  167.         char            fh[32];         /* 32 bytes */
  168.         int            mode;
  169.         int            access;
  170.         unsigned long    offset;
  171.         unsigned long    length;
  172.         int            stat;
  173.         int            sequence;
  174.     } lock = { 0 };
  175.  
  176. #ifdef SCO
  177.  
  178. int  check_access_printer(pn,name)
  179. int pn;
  180. char *name;
  181. {
  182.     int i;
  183.     char **p;
  184.  
  185.         if (debugmode)
  186.           (void) fprintf( stdout, "bwnfsd: [check_access_printer] pn = %d, name = %s\n",
  187.                           pn, name );
  188.  
  189.     if ( printer_access[pn].count == -1)
  190.         {
  191.           if (debugmode)
  192.             (void) fprintf( stdout, "bwnfsd: [check_access_printer] deny all requests\n" );
  193.       return(0);                                   /* Deny all */
  194.     }
  195.     p = printer_access[pn].n.users;
  196.     for ( i = 0 ; i < printer_access[pn].count ; i++)
  197.     {
  198.        if ( strcmp(*p++,name) == 0)
  199.            {
  200.              if (debugmode)
  201.                (void) fprintf( stdout, "bwnfsd: [check_access_printer] request allowed\n" );
  202.          return ( printer_access[pn].access == ALLOW);
  203.        }
  204.     }
  205.         if (debugmode)
  206.           (void) fprintf( stdout, "bwnfsd: [check_access_printer] request denied\n" );
  207.     return( printer_access[pn].access == DENY);
  208. }
  209.  
  210. int check_access(pn,name)
  211. int pn;
  212. char *name;
  213. {
  214.     int i;
  215.     int *pi;
  216.  
  217.         if (debugmode)
  218.           (void) fprintf( stdout, "bwnfsd: [check_access] pn = %d, name = %s\n", pn, name );
  219.  
  220.     if ( printer_access[pn].access != CLASS)
  221.         return(check_access_printer(pn,name));
  222.     pi = printer_access[pn].n.printers;
  223.     for ( i = 0 ; i < printer_access[pn].count; i++)
  224.         if ( check_access_printer(*pi++,name))
  225.         {
  226.           if (debugmode)
  227.             (void) fprintf( stdout, "bwnfsd: [check_access] returns 1\n" );
  228.           return(1);
  229.         }
  230.         if (debugmode)
  231.           (void) fprintf( stdout, "bwnfsd: [check_access] returns 0\n" );
  232.     return(0);
  233. }
  234. #endif
  235.  
  236.  
  237. void free_child()
  238. {
  239.     int    pstatus;
  240.  
  241.         if (debugmode)
  242.           (void) fprintf( stdout, "bwnfsd: [free_child] called\n" );
  243.  
  244.     (void) wait(&pstatus);
  245. #ifdef SIGCHLD
  246.     (void) signal(SIGCHLD,free_child);
  247. #endif
  248. #ifdef SIGCLD
  249.     (void) signal(SIGCLD,free_child);
  250. #endif
  251. }
  252.  
  253. void strlwr(p)
  254.     char *p;
  255. {
  256.     do
  257.     {
  258.        if ( (*p >= 'A') && (*p <= 'Z'))
  259.           *p += 'a'-'A';
  260.     } while (*(++p) != '\00');
  261. }
  262.  
  263.  
  264. void getmask(ip,mask)
  265.     u_long *ip,*mask;
  266. {
  267.     if ( *ip == 0L)
  268.        *mask = 0L;
  269.     else if ( *ip <= 0xffL)
  270.     {
  271.        *ip <<= 24;
  272.        *mask = 0xff000000L;
  273.     }
  274.     else if ( *ip <= 0xffffL)
  275.     {
  276.        *ip <<= 16;
  277.        *mask = 0xffff0000L;
  278.     }
  279.     else if ( *ip <= 0xffffffL)
  280.     {
  281.        *ip <<= 8;
  282.        *mask = 0xffffff00L;
  283.     }
  284.     else
  285.        *mask = 0xffffffffL;
  286. }
  287.  
  288.  
  289. /*
  290.    For -s parameter, returns IP addresses and the associated mask to determine
  291.    if the IP address of the destination machine/network is matches an entry
  292.    in the -s file.
  293. */
  294. int convert_ip(s,ip,mask)
  295.     char *s;
  296.     u_long *ip,*mask;
  297. {
  298.     u_long ia,lip,lmask;
  299.     struct hostent *he;
  300.     struct netent *ne;
  301.  
  302.         if (debugmode)
  303.           (void) fprintf( stdout, "bwnfsd: [convert_ip] s = %s\n", s );
  304.  
  305.     if ( (ia =inet_network(s)) != (~0L))
  306.     {
  307.         lip = ia;
  308.         getmask(&lip,&lmask);
  309.     }
  310.     else if ( (ia =inet_addr(s)) != (~0L))
  311.     {
  312.         lip = ia;
  313.         lmask = 0xffffffffL;
  314.     }
  315.     else if ( (ne = getnetbyname(s)) != NULL)
  316.     {
  317.         lip = ne->n_net;
  318.         getmask(&lip,&lmask);
  319.     }
  320.     else if ( (he = gethostbyname(s)) != NULL)
  321.     {
  322.         lip = * (u_long *) he->h_addr;
  323.         lmask = 0xffffffffL;
  324.     }
  325.     else
  326.         {
  327.            if (debugmode)
  328.              (void) fprintf( stdout, "bwnfsd: [convert_ip] returns 0\n" );
  329.        return(0);
  330.     }
  331.     *ip = lip;
  332.     if ( mask != NULL) *mask = lmask;
  333.         {
  334.           if (debugmode)
  335.             (void) fprintf( stdout, "bwnfsd: [convert_ip] (1) ip = %ul, mask = %ul\n",
  336.                             ip, mask );
  337.         return(1);
  338.       }
  339.         if (debugmode)
  340.           (void) fprintf( stdout, "bwnfsd: [convert_ip] (0) ip = %ul, mask = %ul\n",
  341.                           ip, mask );
  342. }
  343.  
  344. /*
  345.     Read the -s file which lists rules for which hosts can be
  346.         authenticated. Each line is converted to a IP address and mask. Any
  347.         incoming address is ANDed with the mask and compared to IP address,
  348.     if it matches, the action associated with the line is taken.
  349.  
  350.     Valid actions:
  351.         "+" - Perform Validatation check
  352.         "-" - Return Authorization error
  353.         "=" - Tell client to attempt Authorization at new address
  354. */
  355. void read_ips(file)
  356.     char *file;
  357. {
  358.     FILE *f;
  359.     char s1[255],s2[255],line[255],type;
  360.     int    i;
  361.     u_long    ip,mask,redirect_ip;
  362.  
  363.         if (debugmode)
  364.           (void) fprintf( stdout, "bwnfsd: [read_ips] file = %s\n", file );
  365.  
  366.     if ( (f = fopen(file,"r")) == NULL)
  367.     {
  368.         (void) fprintf(stdout,"bwnfsd: [read_ips] \42%s\42 file not found.\n",file);
  369.                 (void) fflush( stdout );
  370.         exit(1);
  371.     }
  372.  
  373.     ips = (struct mm_ips **) malloc(1);
  374.     while ( fgets(line,255,f) != NULL)
  375.     {
  376.        if ( (type = line[0]) != '#')
  377.        {
  378.         i = sscanf(&line[1],"%s %s",s1,s2);
  379.                 if (debugmode)
  380.                   (void) fprintf(stdout, "bwnfsd: [read_ips] parsing <%s>\n", line[1] );
  381.  
  382.             if ( ( i == EOF) || ( i == 0) || ( i > 2) || ( (type != '+') &&
  383.                      ( type != '-') && ( type != '=')) || ( (type == '=') &&
  384.                      ( i != 2) ) || ( (type != '=') && ( i != 1)) )
  385.         {
  386.            (void) fprintf( stdout, "bwnfsd: [read_ips] syntax error, line ignored : %s",line);
  387.         }
  388.         else
  389.          for ( ;;)
  390.                  {
  391.            if ( !convert_ip(s1,&ip,&mask))
  392.            {
  393.               (void) fprintf( stdout, "bwnfsd: [read_ips] \42%s\42 invalid address.\n",s1);
  394.               break;
  395.            }
  396.            if ( i == 2)
  397.               if ( !convert_ip(s2,&redirect_ip,(u_long *)NULL))
  398.               {
  399.                  (void) fprintf(stdout,"bwnfsd: [read_ips] \42%s\42 invalid address.\n",s1);
  400.                  break;
  401.               }
  402.            ips = (struct mm_ips **) realloc(ips,sizeof(ips)*(ips_count+1));
  403.            *(ips+ips_count) = (struct mm_ips *) malloc(sizeof(struct mm_ips));
  404.            (*(ips+ips_count))->type        = type;
  405.            (*(ips+ips_count))->ip          = ip;
  406.            (*(ips+ips_count))->mask        = mask;
  407.            (*(ips+ips_count))->redirect_ip = redirect_ip;
  408.            ips_count++;
  409.            break;
  410.         }
  411.        }
  412.     }
  413.     fclose(f);
  414.         if (debugmode)
  415.           (void) fprintf(stdout,"bwnfsd: [read_ips] exiting with %u values\n", ips_count );
  416. }
  417.  
  418.  
  419. /*
  420.     Add UID to USERNAME translation to cache
  421. */
  422. void add_uid(uid,username)
  423.     int    uid;
  424.     char    *username;
  425. {
  426.         if (debugmode)
  427.           (void) fprintf( stdout, "bwnfsd: [add_uid]  uid <%d>, name <%s>\n",
  428.                           uid, username );
  429.     if ( uids_count++ == 0 )
  430.        uds = (struct mm_uids **) malloc(1);
  431.  
  432.     uds                                = (struct mm_uids **) realloc(uds,sizeof(uds)*uids_count);
  433.         (*(uds+uids_count-1))              = (struct mm_uids *) malloc(sizeof(struct mm_uids));
  434.     (*(uds+uids_count-1))->mm_uid      = uid;
  435.     (*(uds+uids_count-1))->mm_username = (char *) malloc( strlen(username)+1);
  436.     (void) strcpy((*(uds+uids_count-1))->mm_username,username);
  437. }
  438.  
  439.  
  440. /*
  441.     Lookup USERNAME given a UID, also add translation to cache
  442. */
  443. char *get_ui_name(uid)
  444.     int    uid;
  445. {
  446.     struct    passwd *pww;
  447.     int    i;
  448.  
  449.         if (debugmode)
  450.           (void) fprintf(stdout, "bwnfsd: [get_ui_name] uid <%u>\n", uid );
  451.  
  452.     for ( i = 0 ; i < uids_count; i++)
  453.        if ( (*(uds+i))->mm_uid == uid) return ((*(uds+i))->mm_username);
  454.     if ( (pww = getpwuid(uid)) == NULL)
  455.         {
  456.            if (debugmode)
  457.              (void) fprintf( stdout, "bwnfsd: [get_ui_name] getpwuid returned NULL\n" );
  458.            return(NULL);
  459.         }
  460.     add_uid(uid,pww->pw_name);
  461.         if (debugmode)
  462.           (void) fprintf( stdout, "bwnfsd: [get_ui_name] returns %s\n",
  463.                           pww->pw_name );
  464.     return(pww->pw_name);
  465. }
  466.  
  467.  
  468. /*
  469.     Given a UID, GID and USERNAME, create a list of GIDs associated
  470.     with the UID, a maximum of NGRPS GIDS are used.
  471. */
  472. void fill_gid(gd,uid,gid,username)
  473.     struct mm_gidss *gd;
  474.     int    uid,gid;
  475.     char    *username;
  476. {
  477.     struct group *gr;
  478.     struct group *getgrent();
  479.     char    **p;
  480.     int    flag;
  481.  
  482.     add_uid(uid,username);    
  483.         if (debugmode)
  484.           (void) fprintf( stdout, "bwnfsd: [fill_gid] uid = %u, gid = %u, user = %s\n",
  485.                           uid, gid, username );
  486.     flag             = 0;
  487.     gd->mm_uid       = uid;
  488.     gd->mm_gid       = gid;
  489.     gd->mm_gid_count = 0;
  490.     (void) setgrent();
  491.     while ( (gr = getgrent()) != NULL)
  492.     {
  493.         p = gr->gr_mem;
  494.         while ( ((*p) != NULL) && (gd->mm_gid_count < NGRPS))
  495.         {
  496.           if ( strcmp((*p),username) == 0)
  497.           {
  498.              gd->mm_gids[gd->mm_gid_count++] = gr->gr_gid;
  499.              if ( gr->gr_gid == gid) flag=1;
  500.              break;
  501.           }
  502.           p++;
  503.         }
  504.     }
  505.     if  ( (flag == 0) && ( gd->mm_gid_count < NGRPS) )
  506.        gd->mm_gids[gd->mm_gid_count++] = gid;
  507.     (void) endgrent();
  508. }
  509.  
  510.  
  511. /*
  512.     Return a list of GIDs for a given UID. The cache of GIDS/UID is
  513.     updated and used.
  514. */    
  515. struct mm_gidss *get_gids(uid,gid,username)
  516.     int    uid,gid;
  517.     char    *username;
  518. {
  519.     int    i;
  520.  
  521.         if (debugmode)
  522.           (void) fprintf( stdout, "bwnfsd: [mm_gidss] uid = %u, gid = %u, name = %s\n",
  523.                           uid, gid, username );
  524.  
  525.     for ( i = 0 ; i < gids_count; i ++)
  526.        if( (*(gds+i))->mm_uid == uid)
  527.        {
  528.              if (debugmode)
  529.             (void) fprintf( stdout, "bwnfsd: [mm_gidss] gids_count = %u\n",
  530.                          gids_count );
  531.          return(*(gds+i));
  532.        }
  533.  
  534.     if ( gids_count++ == 0 )
  535.        gds = (struct mm_gidss **) malloc(1);
  536.  
  537.     gds = (struct mm_gidss **) realloc(gds,sizeof(gds)*gids_count);
  538.     (*(gds+gids_count-1)) = (struct mm_gidss *) malloc(sizeof(struct mm_gidss));
  539.     (void) fill_gid((*(gds+gids_count-1)),uid,gid,username);
  540.         if (debugmode)
  541.         (void) fprintf( stdout, "bwnfsd: [mm_gidss] gids_count = %u\n",
  542.                     gids_count );
  543.     return(*(gds+gids_count-1));
  544. }
  545.  
  546.     
  547. static struct my_groups
  548.     {
  549.     int my_gid;
  550.     char    *my_name;
  551.     } **g;
  552.  
  553. static int group_count=0;
  554.  
  555. /*
  556.     Return the text name of a GID, if none is found, then the GID
  557.     is convert to a text number.
  558. */
  559. char *get_gr_name(gid)
  560.     int    gid;
  561. {
  562.     static    char gd[32];
  563.     int    i;
  564.  
  565.         if (debugmode)
  566.           (void) fprintf( stdout, "bwnfsd: [get_gr_name] for gid %u\n", gid );
  567.  
  568.     for ( i = 0 ; i < group_count; i++)
  569.         if ( (*(g+i))->my_gid == gid)
  570.         {
  571.           if (debugmode)
  572.             (void) fprintf( stdout, "bwnfds: [get_gr_name] returns %s\n",
  573.                             ((*(g+i))->my_name) );
  574.           return ((*(g+i))->my_name);
  575.         }
  576.     (void) sprintf(gd,"%u",gid);
  577.         if (debugmode)
  578.           (void) fprintf( stdout, "bwnfds: [get_gr_name] returns %s\n", gd );
  579.         return(gd);
  580. }
  581.  
  582.  
  583. /*
  584.     Given a group name, return the GID associated with it.
  585. */
  586. int *get_gr_gid(name)
  587.     char *name;
  588. {
  589.     int    i;
  590.  
  591.         if (debugmode)
  592.           (void) fprintf( stdout, "bwnfsd: [get_gr_gid] for %s\n", name );
  593.     for ( i = 0; i < group_count; i++)
  594.         if ( strcmp((*(g+i))->my_name,name) == 0 )
  595.                 {
  596.                    if (debugmode)
  597.                      (void) fprintf( stdout, "bwnfsd: [get_gr_gid] returns %s\n",
  598.                                      (*(g+i))->my_gid);
  599.              return(&(*(g+i))->my_gid);
  600.                 }
  601.         if (debugmode)
  602.           (void) fprintf( stdout, "bwnfsd: [get_gr_gid] returns NULL\n" );
  603.     return (NULL);
  604. }
  605.  
  606.  
  607. /*
  608.     Cache a list of all group names and their associated GIDS.
  609. */
  610. void get_groups()
  611. {
  612.     struct group *gr;
  613.     struct group *getgrent();
  614.  
  615.         if (debugmode)
  616.           (void) fprintf( stdout, "bwnfsd: [get_groups] called\n" );    
  617.  
  618.     g = (struct my_groups **) malloc(1);
  619.     (void) setgrent();
  620.     while (( gr = getgrent()) != NULL)
  621.     {
  622.       group_count++;
  623.       g = (struct my_groups **) realloc(g,sizeof(g)*group_count);
  624.       (*(g+group_count-1)) = (struct my_groups *) malloc(sizeof(struct my_groups));
  625.       (*(g+group_count-1))->my_name = (char *) malloc(strlen(gr->gr_name)+1);    
  626.  
  627.       (void) strcpy((*(g+group_count-1))->my_name,gr->gr_name);
  628.       (*(g+group_count-1))->my_gid = gr->gr_gid;
  629.     }
  630.     (void) endgrent();
  631. }
  632.  
  633.  
  634. #ifdef SCO
  635.  
  636. void get_class_list(char *name,int pn)
  637. {
  638.     FILE *f;
  639.     char line[128];
  640.     char file_name[64];
  641.     int i;
  642.  
  643.         if (debugmode)
  644.           (void) fprintf( stdout, "bwnfsd: [get_class_list] name = %s, pn =%u\n",
  645.                           name, pn );
  646.     printer_access[pn].access     = CLASS;
  647.     printer_access[pn].n.printers = NULL;
  648.     printer_access[pn].count      = 0;
  649.     sprintf(file_name,"/usr/spool/lp/admins/lp/classes/%s",name);
  650.     
  651.     if ( (f = fopen(file_name,"r")) == NULL)
  652.         {
  653.           if (debugmode)
  654.             (void) fprintf( stdout, "bwnfsd: [get_class_list] open file %s returned NULL\n",
  655.                             file_name );
  656.       return;
  657.     }
  658.     while ( fgets(line,128,f) != NULL)
  659.     {
  660.         *(line+strlen(line)-1) = '\0';
  661.         for ( i = 0 ; i < pn; i++)
  662.            if ( strcmp(line,printers[i]) == 0)
  663.            {
  664.             if ( printer_access[pn].count++ == 0)
  665.                 printer_access[pn].n.printers = malloc(sizeof(int));
  666.             else
  667.                 printer_access[pn].n.printers = realloc(printer_access[pn].n.printers,printer_access[pn].count * sizeof(int));    
  668.             *(printer_access[pn].n.printers+printer_access[pn].count-1) = i;
  669.             break;
  670.                 }
  671.     }
  672.     fclose(f);
  673. }
  674.  
  675. void get_access(char *name,int pn)
  676. {
  677.     FILE *f;
  678.     char line[128];
  679.     char file_name[64];
  680.  
  681.         if (debugmode)
  682.           (void) fprintf( stdout, "bwnfsd: [get_access] name = %s, pn =%u\n",
  683.                           name, pn );
  684.     printer_access[pn].access  = ALLOW;
  685.     printer_access[pn].n.users = NULL;
  686.     printer_access[pn].count   = 0;
  687.     sprintf(file_name, LP_ALLOW,name);
  688.     if ( (f = fopen(file_name,"r")) != NULL)
  689.     {
  690.                 if (debugmode)
  691.                   (void) fprintf( stdout, "bwnfsd: [get_access] reading %s\n",
  692.                                   file_name );
  693.         while ( fgets(line,128,f) != NULL)
  694.         {
  695.             *(line+strlen(line)-1) = '\0';
  696.             if ( strcmp(line,"any") == 0)
  697.             {
  698.                 printer_access[pn].n.users = NULL;
  699.                 printer_access[pn].count = 0;
  700.                 break;    
  701.             }
  702.             if ( printer_access[pn].count++ == 0)
  703.                 printer_access[pn].n.users = malloc(sizeof(char*));
  704.             else
  705.                 printer_access[pn].n.users = realloc(printer_access[pn].n.users,printer_access[pn].count * sizeof(char*));    
  706.             *(printer_access[pn].n.users+printer_access[pn].count-1) = strdup(line);
  707.         }
  708.         fclose(f);
  709.         if ( printer_access[pn].count != 0)
  710.         {
  711.           if (debugmode)
  712.             (void) fprintf( stdout, "bwnfsd: [get_access] access count = %u\n",
  713.                    printer_access[pn].count );
  714.           return;
  715.                 }        
  716.     }
  717.     else
  718.     {
  719.           if (debugmode)
  720.             (void) fprintf( stdout, "bwnfsd: [getaccess] unable to open %s\n",
  721.                             file_name );
  722.     }
  723.     printer_access[pn].access = DENY;
  724.     sprintf(file_name,LP_DENY,name);
  725.     if ( (f = fopen(file_name,"r")) != NULL)
  726.     {
  727.         while ( fgets(line,128,f) != NULL)
  728.         {
  729.             *(line+strlen(line)-1) = '\0';
  730.             if ( strcmp(line,"any") == 0)
  731.             {
  732.                 printer_access[pn].n.users = NULL;
  733.                 printer_access[pn].count   = -1;
  734.                 break;    
  735.             }
  736.             if ( printer_access[pn].count++ == 0)
  737.                 printer_access[pn].n.users = malloc(sizeof(char*));
  738.             else
  739.                 printer_access[pn].n.users = realloc(printer_access[pn].n.users,printer_access[pn].count * sizeof(char*));    
  740.             *(printer_access[pn].n.users+printer_access[pn].count-1) = strdup(line);
  741.         }
  742.         fclose(f);
  743.     }
  744.     else
  745.     {
  746.           if (debugmode)
  747.             (void) fprintf( stdout, "bwnfsd: [getaccess] unable to open %s\n",
  748.                             file_name );
  749.     }
  750.     
  751. }
  752.  
  753.  
  754. void get_printer_list(status_file,type)
  755. char *status_file;
  756. int  type;
  757. {
  758.     FILE *f;
  759.     char line[128],name[32];
  760.     int  i;
  761.  
  762.         if (debugmode)
  763.           (void) fprintf( stdout, "bwnfsd: [get_printer_list] file = %s, type = %u\n",
  764.                           status_file, type );
  765.     if ( (f = fopen(status_file,"r")) == NULL)
  766.         {
  767.           if (debugmode)
  768.             (void) fprintf( stdout, "bwnfsd: [get_printer_list] unable to open %s\n",
  769.                             status_file );
  770.       return;
  771.     }
  772.     while ( fgets(line,128,f) != NULL)
  773.        if ( strncmp(line,"=====",5) == 0)
  774.        {
  775.         if ( fgets(name,32,f) == NULL) break;
  776.         if ( fgets(line,128,f) == NULL) break;
  777.                 if (debugmode)
  778.                   (void) fprintf( stdout, "bwnfsd: [get_printer_list] name = %s, line = %s\n",
  779.                                   name, line );
  780.         for ( i = 0; i < strlen(line); i++)
  781.             if ( strncmp(&line[i],"accepting",9) == 0) break;
  782.         if ( i == strlen(line)) continue;
  783.         *(name+strlen(name)-1) = '\0';
  784.         printers[num_printers] = strdup(name);
  785.         if ( type == 0 )
  786.             get_access(name,num_printers++);
  787.         else
  788.             get_class_list(name,num_printers++);
  789.        }
  790.     fclose(f);
  791. }
  792. #endif
  793.  
  794.  
  795. /*
  796.     Cache a list of available printers, BSD code searchs the /etc/printcap
  797.     file. Creating a dummy /etc/printcap can also work.
  798. */
  799. void get_printers()
  800. {
  801. #ifndef SCO
  802.   static char line[132];
  803.   char *p,*p1;
  804.   FILE *f;
  805.   int  i;
  806. #endif
  807.  
  808.   if (debugmode)
  809.     (void) fprintf( stdout, "bwnfsd: [get_printers] called\n" );
  810.  
  811.   num_printers = 0;
  812. #ifdef SCO
  813.     get_printer_list(P_STATUS,0);
  814.     get_printer_list(C_STATUS,1);
  815. }
  816. #else
  817.   if ( (f = fopen(PRINTCAP, "r")) == NULL)
  818.   {
  819.     (void) fprintf( stdout, "bwnfsd: File %s was not found.\n" , PRINTCAP);
  820.     (void) fprintf( stdout, "        No printers are available for use.\n" );
  821.     return;
  822.   }
  823.  
  824.   while ( fgets(line,132,f) != NULL)
  825.   {
  826.      p = &line[0];
  827.      while ( (*p == ' ') || (*p == '\t') ) p++;
  828.      while (( *p != '#') && ( *p != ':') )
  829.        {
  830.        p1 = strchr(p,'|');
  831.        if ( p1 == NULL) p1 = strchr(p,':');
  832.            if ( p1 != NULL)
  833.            {
  834.               *p1 = '\000';
  835.               printers[num_printers] = (char *) malloc(strlen(p) + 1);
  836.               (void) strcpy(printers[num_printers++],p);
  837.               p = p1 +1;
  838.            }
  839.            else
  840.               *p = '#';
  841.         }
  842.  
  843.   }
  844.   fclose(f);
  845.  
  846.   if (debugmode)
  847.   {
  848.     (void) fprintf( stdout, "bwnfsd: [get_printers] Following devices are available\n" );
  849.     for ( i = 0; i < num_printers; i++)
  850.       (void) fprintf( stdout, "bwnfsd:                 %s\n", printers[i] );
  851.   }
  852.  
  853. }
  854. #endif
  855.  
  856.  
  857. static struct var_file {
  858.         int          status;
  859.         int             dir_size;
  860.         char             *dir_handle;
  861. } f;
  862.  
  863. /*
  864.     DOS 3.1 Sharing and Unsharing code. Uses the same format for rpc.lockd
  865.     as BWNFSD, so some parameters are ignored. The cookie under rpc.lockd
  866.     must be 4 bytes long under BWNFSD.
  867. */
  868. xdr_share(xdrsp,l)
  869.     XDR *xdrsp;
  870.     struct locking *l;
  871. {
  872.    int    i;
  873.    char g[32];
  874.    char *p;
  875.  
  876.    if (debugmode > 1)
  877.    {
  878.      (void) fprintf( stdout, "bwnfsd: [xdr_share] called for %s, ofs = %ld, len = %ld\n",
  879.                      l->name, l->offset, l->length );
  880.      (void) fprintf( stdout, "bwnfsd:             mode = %u, access = %u, stat = %u, sequence = %u\n",
  881.                      l->mode, l->access, l->stat, l->sequence );
  882.    }
  883.    if (!xdr_int(xdrsp, &l->cookie)) return(0); /* Get length of cookie, MUST be 4 */
  884.    if ( l->cookie != 4)             return(0);
  885.    if (!xdr_int(xdrsp, &l->cookie)) return(0); /* Get cookie as an unsigned long */
  886.  
  887.    p = l->name;
  888.    if (!xdr_string(xdrsp,&p,17))    return(0);
  889.    p = l->fh;
  890.    if (!xdr_bytes(xdrsp,&p,&i,32))  return(0);
  891.    p = g;
  892.    if (!xdr_bytes(xdrsp,&p,&i,32))  return(0);
  893.    if (!xdr_int(xdrsp, &l->mode))   return(0);
  894.    if (!xdr_int(xdrsp, &l->access)) return(0);
  895.  
  896.    if (debugmode)
  897.      (void) fprintf( stdout, "bwnfsd: [xdr_share] returns (1)\n" );
  898.  
  899.    return(1);
  900. }
  901.  
  902.  
  903. /*
  904.     DOS 3.1 Share response.
  905. */
  906. xdr_shareres(xdrsp,l)
  907.     XDR *xdrsp;
  908.     struct locking *l;
  909. {
  910.    int i;
  911.    char *p;
  912.  
  913.    if (debugmode)
  914.      (void) fprintf( stdout, "bwnfsd: [xdr_shareres] called by %s\n", l->name );
  915.    i = 4;
  916.    if (!xdr_int(xdrsp, &i))         return(0); /* Send length of cookie, MUST be 4 */
  917.    if (!xdr_int(xdrsp, &l->cookie)) return(0); /* Send cookie as an unsigned long */
  918.    if (!xdr_int(xdrsp,&l->stat))    return(0);
  919.    l->sequence++;
  920.    if (!xdr_int(xdrsp,&l->sequence)) return(0);
  921.  
  922.    if (debugmode)
  923.      (void) fprintf( stdout, "bwnfsd: [xdr_shareres] returns (1)\n" );
  924.    return(1);
  925. }
  926.  
  927.  
  928. /*
  929.     DOS 3.1 locking request. Note that several parameters are ignored.
  930. */
  931. xdr_lock(xdrsp,l)
  932.     XDR *xdrsp;
  933.     struct locking *l;
  934. {
  935.    int    i;
  936.    char g[32];
  937.    char *p;
  938.  
  939.    if (debugmode)
  940.    {
  941.      (void) fprintf( stdout, "bwnfsd: [xdr_lock] called by %s\n", l->name );
  942.      if (debugmode > 1)
  943.        (void) fprintf( stdout, "bwnfsd:            ofs = %ul, len = %ul\n",
  944.                        l->offset, l->length );
  945.    }
  946.    if (!xdr_int(xdrsp, &l->cookie)) return(0);  /* Get length of cookie, MUST be 4 */
  947.    if (!xdr_int(xdrsp, &l->cookie)) return(0);  /* Get cookie as an unsigned long */
  948.    if (!xdr_int(xdrsp,&i))          return(0);  /* block */
  949.    if (!xdr_int(xdrsp,&i))          return(0);  /* exclusive */
  950.    p = l->name;
  951.    if (!xdr_string(xdrsp,&p,17))    return(0);
  952.    p = l->fh;
  953.    if (!xdr_bytes(xdrsp,&p,&i,32))  return(0);
  954.    p = g;
  955.    if (!xdr_bytes(xdrsp,&p,&i,32))  return(0);   /* oh */
  956.    if (!xdr_int(xdrsp,&i))          return(0);  /* svid */
  957.    if (!xdr_int(xdrsp, &l->offset)) return(0);
  958.    if (!xdr_int(xdrsp, &l->length)) return(0);
  959.    if (debugmode > 1)
  960.      (void) fprintf( stdout, "bwnfsd: [xdr_lock] returns (1)\n" );
  961.    return(1);
  962. }
  963.  
  964.  
  965. /*
  966.     DOS 3.1 unlock request. Note that several parameters are ignored.
  967. */
  968. xdr_unlock(xdrsp,l)
  969.     XDR *xdrsp;
  970.     struct locking *l;
  971. {
  972.    int    i;
  973.    char g[32];
  974.    char *p;
  975.  
  976.    if (debugmode)
  977.    {
  978.      (void) fprintf( stdout, "bwnfsd: [xdr_unlock] called by %s\n", l->name );
  979.      if (debugmode > 1)
  980.        (void) fprintf( stdout, "bwnfsd:              ofs = %ul, len = %ul\n",
  981.                        l->offset, l->length );
  982.    }
  983.    if (!xdr_int(xdrsp, &l->cookie)) return(0);  /* Get length of cookie, MUST be 4 */
  984.    if (!xdr_int(xdrsp, &l->cookie)) return(0);  /* Get cookie as an unsigned long */
  985.  
  986.    p = l->name;
  987.    if (!xdr_string(xdrsp,&p,17))    return(0);
  988.    p = l->fh;
  989.    if (!xdr_bytes(xdrsp,&p,&i,32))  return(0);
  990.    p = g;
  991.    if (!xdr_bytes(xdrsp,&p,&i,32))  return(0);   /* oh */
  992.    if (!xdr_int(xdrsp,&i))          return(0);   /* svid */
  993.    if (!xdr_int(xdrsp, &l->offset)) return(0);
  994.    if (!xdr_int(xdrsp, &l->length)) return(0);
  995.    if (debugmode > 1)
  996.      (void) fprintf( stdout, "bwnfsd: [xdr_unlock] returns (1)\n" );
  997.    return(1);
  998. }
  999.  
  1000.  
  1001.  
  1002. /*
  1003.     Send Locking response.
  1004. */
  1005. xdr_res(xdrsp,l)
  1006.     XDR *xdrsp;
  1007.     struct locking *l;
  1008. {
  1009.    int i;
  1010.    char *p;
  1011.  
  1012.    if (debugmode > 1)
  1013.      (void) fprintf( stdout, "bwnfsd: [xdr_res] called\n" );
  1014.    i = 4;
  1015.    if (!xdr_int(xdrsp, &i))         return(0); /* Send length of cookie, MUST be 4 */
  1016.    if (!xdr_int(xdrsp, &l->cookie)) return(0); /* Send cookie as an unsigned long */
  1017.    if (!xdr_int(xdrsp,&l->stat))    return(0);
  1018.    if (debugmode)
  1019.      (void) fprintf( stdout, "bwnfsd: [xdr_res] returns (1)\n" );
  1020.    return(1);
  1021. }
  1022.  
  1023.  
  1024. /*
  1025.     Remove all DOS 3.1 locks and shares, not that the PC's name is
  1026.     a maximum of 16 chaarcters.
  1027. */
  1028. xdr_get_lock_name(xdrsp,l)
  1029.     XDR *xdrsp;
  1030.     char *l;
  1031. {
  1032.    if (debugmode)
  1033.      (void) fprintf( stdout, "bwnfsd: [xdr_get_lock_name] called\n" );
  1034.    return(xdr_string(xdrsp,&l,17));
  1035. }
  1036.  
  1037.  
  1038.  
  1039. /*
  1040.     Send a redirect to a new IP during an authorization request.
  1041. */
  1042. xdr_new_ip(xdrsp, ip)
  1043.         XDR *xdrsp;
  1044.         u_long *ip;
  1045. {
  1046.    int i;
  1047.  
  1048.    if (debugmode)
  1049.      (void) fprintf( stdout, "bwnfsd: [xdr_new_ip] called\n" );
  1050.    i = 3;
  1051.    if (!xdr_int(xdrsp, &i)) return(0);
  1052.    if (!xdr_int(xdrsp, ip)) return(0);
  1053.    if (debugmode)
  1054.      (void) fprintf( stdout, "bwnfsd: [xdr_new_ip] returns (1)\n" );
  1055.    return(1);
  1056. }
  1057.  
  1058.  
  1059. /*
  1060.     Get GROUP name.
  1061. */
  1062. xdr_g_string(xdrsp, st)
  1063.         XDR *xdrsp;
  1064.         char *st;
  1065. {
  1066.   char *p;
  1067.  
  1068.   if (debugmode)
  1069.     (void) fprintf( stdout, "bwnfsd: [xdr_g_string] called\n" );
  1070.   p = st;
  1071.   if (!xdr_string(xdrsp,&p,32)) return(0);
  1072.   if (debugmode)
  1073.     (void) fprintf( stdout, "bwnfsd: [xdr_g_string] returns (1)\n" );
  1074.   return(1);
  1075. }
  1076.  
  1077.  
  1078. /*
  1079.     Send Status and GID
  1080. */
  1081. xdr_send_gid(xdrsp, st)
  1082.         XDR *xdrsp;
  1083.         char *st;
  1084. {
  1085.   int   *i,j;
  1086.  
  1087.   if (debugmode)
  1088.     (void) fprintf( stdout, "bwnfsd: [xdr_send_gid] called with st = %s\n",
  1089.                     st );
  1090.   i = get_gr_gid(st);
  1091.   if ( i == NULL)
  1092.   {
  1093.      j = 2;    /* Error Status */
  1094.      if (!xdr_int(xdrsp,&j)) return(0);
  1095.   }
  1096.   else
  1097.   {
  1098.      j = 0;
  1099.      if ( !xdr_int(xdrsp,&j) ) return(0);
  1100.      if ( !xdr_int(xdrsp,i) )  return(0);
  1101.   }
  1102.   if (debugmode)
  1103.     (void) fprintf( stdout, "bwnfsd: [xdr_send_gid] returns (1)\n" );
  1104.   return(1);
  1105. }
  1106.  
  1107.  
  1108. /*
  1109.     Get list of UIDs to translate to text.
  1110. */
  1111. xdr_nuids(xdrsp, luids)
  1112.         XDR *xdrsp;
  1113.         int    luids[NUSRS+1];
  1114. {
  1115.   int i;
  1116.  
  1117.   if (debugmode)
  1118.     (void) fprintf( stdout, "bwnfsd: [xdr_nuids] called\n" );
  1119.   if ( !xdr_int(xdrsp,&luids[0]) ) return(0);
  1120.   if ( ( luids[0] < 0) || ( luids[0] > 16) ) luids[0]=0;
  1121.   for ( i = 1; i <= luids[0]; i++)
  1122.      if ( !xdr_int(xdrsp,&luids[i])) return(0);
  1123.   if (debugmode)
  1124.     (void) fprintf( stdout, "bwnfsd: [xdr_nuids] returns (1)\n" );
  1125.   return(1);
  1126. }
  1127.  
  1128.  
  1129. /*
  1130.     Get list of GIDs to translate to text.
  1131. */
  1132. xdr_ngids(xdrsp, lgids)
  1133.         XDR *xdrsp;
  1134.         int    lgids[NGRPS+1];
  1135. {
  1136.   int i;
  1137.  
  1138.   if (debugmode)
  1139.     (void) fprintf( stdout, "bwnfsd: [xdr_ngids] called\n" );
  1140.  
  1141.   if ( !xdr_int(xdrsp,&lgids[0]) ) return(0);
  1142.   if ( ( lgids[0] < 0) || ( lgids[0] > 16) ) lgids[0]=0;
  1143.   for ( i = 1; i <= lgids[0]; i++)
  1144.      if ( !xdr_int(xdrsp,&lgids[i])) return(0);
  1145.   if (debugmode)
  1146.     (void) fprintf( stdout, "bwnfsd: [xdr_ngids] returns (1)\n" );
  1147.   return(1);
  1148. }
  1149.  
  1150.  
  1151. /*
  1152.     Send Usernames translated from UIDS.
  1153. */
  1154. xdr_send_usernames(xdrsp, luids)
  1155.         XDR *xdrsp;
  1156.         int    luids[NUSRS+1];
  1157. {
  1158.   int i,j;
  1159.   char *p;
  1160.  
  1161.   if (debugmode)
  1162.     (void) fprintf( stdout, "bwnfsd: [xdr_send_usernames] called\n" );
  1163.   for ( i = 1; i <= luids[0]; i++)
  1164.   {
  1165.     p = get_ui_name(luids[i]);
  1166.     if (debugmode)
  1167.       (void) fprintf( stdout, "bwnfsd: [xdr_send_usernames] p = %s\n", p );
  1168.     if ( p == NULL)
  1169.     {
  1170.     j = 0;
  1171.     if( !xdr_int(xdrsp,&j))return(0);
  1172.     }
  1173.     else
  1174.     {
  1175.        if ( !xdr_string(xdrsp,&p,32)) return(0);
  1176.     }
  1177.   }
  1178.   if (debugmode)
  1179.     (void) fprintf( stdout, "bwnfsd: [xdr_send_usernames] returns (1)\n" );
  1180.   return(1);
  1181. }
  1182.  
  1183.  
  1184. /*
  1185.     Send Group names translated from GIDS.
  1186. */
  1187. xdr_send_names(xdrsp, lgids)
  1188.         XDR *xdrsp;
  1189.         int    lgids[NGRPS+1];
  1190. {
  1191.   int i,j;
  1192.   char *p;
  1193.  
  1194.   if (debugmode)
  1195.     (void) fprintf( stdout, "bwnfsd: [xdr_send_names] called\n" );
  1196.   for ( i = 1; i <= lgids[0]; i++)
  1197.   {
  1198.     p = get_gr_name(lgids[i]);
  1199.     if (debugmode)
  1200.       (void) fprintf( stdout, "bwnfsd: [xdr_send_names] p = %s\n", p );
  1201.     if ( p == NULL)
  1202.     {
  1203.     j = 0;
  1204.     if( !xdr_int(xdrsp,&j)) return(0);
  1205.     }
  1206.     else
  1207.     {
  1208.        if ( !xdr_string(xdrsp,&p,32)) return(0);
  1209.     }
  1210.   }
  1211.   if (debugmode)
  1212.     (void) fprintf( stdout, "bwnfsd: [xdr_send_names] returns (1)\n" );
  1213.   return(1);
  1214. }
  1215.  
  1216.  
  1217. /*
  1218.     Return fhandle of spool directory. Note a loop of XDR_INTS is
  1219.     used to allow this to compile on all systems.
  1220. */
  1221. xdr_file(xdrsp, file_var)
  1222.         XDR *xdrsp;
  1223.         struct var_file *file_var;
  1224. {
  1225.   int   i;
  1226.  
  1227.   if (debugmode)
  1228.     (void) fprintf( stdout, "bwnfsd: [xdr_file] called\n" );
  1229.   if (!xdr_int(xdrsp,&file_var->status)) return(0);
  1230.   if (file_var->status !=0)
  1231.   {
  1232.     if (debugmode > 1)
  1233.       (void) fprintf( stdout, "bwnfsd: [xdr_file] status = %u, returns (1)\n",
  1234.                       file_var->status );
  1235.     return(1);
  1236.   }
  1237.   for (i = 0 ; i < 32; i+=4)
  1238.      if (!xdr_int(xdrsp, (&file_var->dir_handle[0]) + i)) return(0);
  1239.   if (debugmode)
  1240.     (void) fprintf( stdout, "bwnfsd: [xdr_file] returns (1)\n" );
  1241.   return(1);
  1242. }
  1243.  
  1244.  
  1245. /*
  1246.     Spool a file to the printer:
  1247.  
  1248.         Parameters:
  1249.             printer_name (fixed 11 bytes)
  1250.             file_name    (fixed 8 bytes) (Internet Address in Hex).
  1251.             extension     xdr_int ( filename is form C02A0405.xxx)
  1252. */
  1253. xdr_print(xdrsp )
  1254.    XDR *xdrsp;
  1255. {
  1256.    struct stat buf;
  1257.    struct passwd *pw1;
  1258.    char  *p;
  1259.    int   i;
  1260.  
  1261.    if (debugmode)
  1262.      (void) fprintf( stdout, "bwnfsd: [xdr_print] called\n" );
  1263.    i = 11;
  1264.    p = printer;
  1265.    if (!xdr_bytes(xdrsp,&p,&i, 11) )
  1266.    {
  1267.      if (debugmode > 1)
  1268.        (void) fprintf( stdout, "bwnfsd: [xdr_print] printer = %s, file = %s, ext = %s\n",
  1269.                        printer, file_name, extension );
  1270.      return(0);
  1271.    }
  1272.    printer[11]=' ';
  1273.    *strchr(printer, ' ') = '\0';
  1274.    i = 8;
  1275.    p = file_name;
  1276.    if (!xdr_bytes(xdrsp,&p,&i, 8) )
  1277.    {
  1278.      if (debugmode > 1)
  1279.        (void) fprintf( stdout, "bwnfsd: [xdr_print] printer = %s, file = %s, ext = %s\n",
  1280.                        printer, file_name, extension );
  1281.      return(0);
  1282.    }
  1283.    file_name[8]='\0';
  1284.    if (!xdr_int(xdrsp,&extension))
  1285.    {
  1286.      if (debugmode > 1)
  1287.        (void) fprintf( stdout, "bwnfsd: [xdr_print] printer = %s, file = %s, ext = %s\n",
  1288.                        printer, file_name, extension );
  1289.      return(0);
  1290.    }
  1291.    strlwr(file_name);
  1292.    (void) sprintf(file,LP_FILE,spool_dir,file_name,extension);
  1293. #ifdef SCO
  1294.    (void) sprintf(file1,LP_FILE1,spool_dir,file_name,extension);
  1295. #else
  1296.    (void) sprintf(file1,LP_FILE1,spool_dir,file_name,extension);
  1297. #endif
  1298.    if (debugmode > 1)
  1299.      (void) fprintf( stdout, "bwnfsd: [xdr_print] f = %s, f1 = %s\n",
  1300.                      file, file1 );
  1301.    jobname  = NULL;
  1302.    do_print = -1;
  1303.    if ( stat(file,&buf) == 0 )
  1304.    {
  1305.       do_print = rename(file,file1);
  1306.       pw1 = getpwuid( (int) buf.st_uid);
  1307.       if (pw1 != NULL)
  1308.       {
  1309.         if (debugmode)
  1310.           (void) fprintf( stdout, "bwnfsd: [xdr_print] jobname = %s\n",
  1311.                           pw1->pw_name );
  1312.      jobname = pw1->pw_name;
  1313.       }
  1314.    }
  1315.    if (debugmode)
  1316.      (void) fprintf( stdout, "bwnfsd: [xdr_print] returns (1)\n" );
  1317.    return(1);
  1318. }
  1319.  
  1320.  
  1321. struct auth_struct
  1322. {
  1323.    u_long ip;
  1324.    int   type;
  1325.    char  device[13];
  1326.    char  login_text[64];
  1327.    char  *username;
  1328.    char  *password;
  1329. } auth_request;
  1330.  
  1331. /*
  1332.     Request Authorization:
  1333.         Parameters:
  1334.             IP_Address of server host (XDR_INT)
  1335.             Type of request (XDR_INT) ( 4 - disk, 3 - printer)
  1336.             Device to link  (XDR_BYTES max 12) (printer name)
  1337.             Username/Password (XDR_BYTES max 64)
  1338. */
  1339. xdr_auth_request(xdrsp, auth)
  1340.   XDR     *xdrsp;
  1341.   struct  auth_struct *auth;
  1342. {
  1343.   int   i,j,x,y;
  1344.   char  *p;
  1345.  
  1346.   if (!xdr_int(xdrsp,&auth->ip))   return(0);
  1347.   if (!xdr_int(xdrsp,&auth->type)) return(0);
  1348.   i = 11;
  1349.   p = auth->device;
  1350.   if (!xdr_bytes(xdrsp,&p,&i, 12) ) return(0);
  1351.   auth->device[11]= ' ';
  1352.   p=strchr(auth->device, ' ');
  1353.   if ( p == NULL) return(0);
  1354.   *p='\00';
  1355.   i = 64;
  1356.   p = auth->login_text;
  1357.   if (!xdr_bytes(xdrsp,&p,&i,64) ) return(0);
  1358.   if ( i < 6) auth->type = -1;
  1359.   p = auth->login_text;
  1360.   for (x = -1, j = 0; j < i; j++)
  1361.   {
  1362.      y = *p;
  1363.      x = *p ^ x;
  1364.      *p++ = x;
  1365.      x = y;
  1366.   }
  1367.   auth->username = auth->login_text + 2;
  1368.   auth->password = auth->username + strlen(auth->username) + 1;
  1369.   if (debugmode)
  1370.   {
  1371.      (void) fprintf( stdout, "bwnfsd: [xdr_auth_request] called\n" );
  1372.      (void) fprintf( stdout, "bwnfsd: Link to %d:%d:%d:%d\n",
  1373.                      (auth->ip >> 24 ) & 0xff, (auth->ip >> 16)  & 0xff,
  1374.                      (auth->ip >>  8 ) & 0xff, (auth->ip )       & 0xff );
  1375.      (void) fprintf( stdout, "bwnfsd: Request type : %u\n", auth->type );
  1376.      (void) fprintf( stdout, "bwnfsd: Device name  : %s\n", auth->device );
  1377.      (void) fprintf( stdout, "bwnfsd: Username     : %s\n", auth->username );
  1378.      (void) fprintf( stdout, "bwnfsd: Password     : %s\n", auth->password );
  1379.  
  1380.   }
  1381.   if (debugmode)
  1382.      (void) fprintf( stdout, "bwnfsd: [xdr_auth_request] returns (1)\n" );
  1383.   return(1);
  1384. }
  1385.  
  1386.  
  1387. /*
  1388.     Send successfull authorization reply.
  1389.         Results:
  1390.                   UID (XDR_INT)
  1391.                   GID (XDR_INT)
  1392.                   GID count (XDR_INT)
  1393.                   GIDs (XDR_INT)    (GID count entries)
  1394. */
  1395. xdr_pw(xdrsp,pwd)
  1396.   XDR   *xdrsp;
  1397.   struct passwd *pwd;
  1398. {
  1399.   int   i;
  1400.   struct mm_gidss *gg;
  1401.  
  1402.  
  1403.   if (debugmode)
  1404.   {
  1405.      (void) fprintf( stdout, "bwnfsd: [xdr_pw] called\n" );
  1406.   }
  1407.   i  = 0;
  1408.   gg = get_gids(pwd->pw_uid,pwd->pw_gid,pwd->pw_name);
  1409.   if (debugmode > 1)
  1410.   {
  1411.      (void) fprintf( stdout, "bwnfsd: uid = %u, gid = %u, gids = %u\n",
  1412.                      gg->mm_uid, gg->mm_gid, gg->mm_gids[0] );
  1413.   }
  1414.   if( !xdr_int(xdrsp,&i) ) return(0);
  1415.   i = pwd->pw_uid;
  1416.   if( !xdr_int(xdrsp,&i) ) return(0);
  1417.   i = pwd->pw_gid;
  1418.   if( !xdr_int(xdrsp,&i) ) return(0);
  1419.   if( !xdr_int(xdrsp,&gg->mm_gid_count) ) return(0);
  1420.   for ( i = 0 ; i < gg->mm_gid_count; i++)
  1421.      if ( !xdr_int(xdrsp,&gg->mm_gids[i]) ) return(0);
  1422.  
  1423.   if (debugmode > 1)
  1424.      (void) fprintf( stdout, "bwnfsd: [xdr_pw] returns (1)\n" );
  1425.   return(1);
  1426. }
  1427.  
  1428.  
  1429. #ifdef SCO
  1430. #define SecureWare 1
  1431. #include <sys/security.h>
  1432. #include <sys/audit.h>
  1433. #include <prot.h>
  1434. #endif
  1435.  
  1436.  
  1437. /*
  1438.     The main RPC routine.
  1439. */
  1440. create_spool(rqstp, transp)
  1441.   struct svc_req *rqstp;
  1442.   SVCXPRT *transp;
  1443. {
  1444.   struct   passwd *pw;
  1445. #ifdef SHADOW
  1446.       struct   spwd *sp;
  1447. #endif
  1448. #ifdef SCO
  1449.     struct pr_passwd *prpw;
  1450. #endif
  1451.   int   i;
  1452.   u_long    r_ip,i_ip;
  1453.  
  1454.   if (debugmode)
  1455.      (void) fprintf( stdout, "bwnfsd: [create_spool] called\n" );
  1456.   switch(rqstp->rq_proc)
  1457.   {
  1458.   case NULLPROC:
  1459.      if (!svc_sendreply(transp, xdr_void, 0))
  1460.      {
  1461.         (void) fprintf( stdout, "bwnfsd: [create_spool] (1) Can't reply to RPC call\n");
  1462.      }
  1463.      return;
  1464.   case SPOOL_INQUIRE:
  1465.      if (!svc_sendreply(transp, xdr_file, &f))
  1466.      {
  1467.         (void) fprintf( stdout, "bwnfsd : [create_spool] (2) Can't reply to RPC call\n");
  1468.      }
  1469.      return;
  1470.   case SPOOL_FILE:
  1471.      if (!svc_getargs(transp,xdr_print, NULL))
  1472.      {
  1473.         svcerr_decode(transp);
  1474.     return;
  1475.      }
  1476.      if (!svc_sendreply(transp, xdr_void, 0))
  1477.      {
  1478.         (void) fprintf( stdout, "bwnfsd: [create_spool] (3) Can't reply to RPC call\n");
  1479.      }    
  1480.      if ( do_print == 0)
  1481.         if ( fork() == 0)
  1482.         {
  1483.        print_it(file1,printer,jobname);
  1484.              exit(0);
  1485.         }
  1486.      return;
  1487.   case AUTHORIZE:
  1488.      if (!svc_getargs(transp,xdr_auth_request, &auth_request))
  1489.      {
  1490.         svcerr_decode(transp);
  1491.     return;
  1492.      }
  1493.      if (auth_request.type == -1)
  1494.      {
  1495.         i = 1;
  1496.         if (!svc_sendreply(transp, xdr_int, &i))
  1497.         {
  1498.            (void) fprintf( stdout, "bwnfsd: [create_spool] (4) Can't reply to RPC call\n");
  1499.         }
  1500.         return;
  1501.      }
  1502.      if ( A_flag == 0)
  1503.      {
  1504.         if( s_flag == 0)
  1505.     {
  1506.       if ( ntohl(auth_request.ip) != my_ip)
  1507.       {
  1508.               i = 1;
  1509.               if (!svc_sendreply(transp, xdr_int, &i))
  1510.               {
  1511.                  (void) fprintf( stdout, "bwnfsd: [create_spool] (5) Can't reply to RPC call\n");
  1512.               }
  1513.               return;
  1514.       }
  1515.     }
  1516.     else
  1517.     {
  1518.     for (i = 0; i < ips_count; i++)
  1519.         {
  1520.        if ( ( (*(ips+i))->mask & ntohl(auth_request.ip)) == (*(ips+i))->ip)
  1521.        {
  1522.           switch((*(ips+i))->type)
  1523.           {
  1524.           case '+' :
  1525.              i=ips_count+1;
  1526.              break;
  1527.           case '-' :
  1528.                          i = 1;
  1529.                          if (!svc_sendreply(transp, xdr_int, &i))
  1530.                          {
  1531.                             (void) fprintf( stdout, "bwnfsd: [create_spool] (5.1) Can't reply to RPC call\n");
  1532.                          }
  1533.                          return;
  1534.           case '=' :
  1535.              i_ip = (*(ips+i))->redirect_ip;
  1536.              if (!svc_sendreply(transp, xdr_new_ip, &i_ip))
  1537.                  {
  1538.                         (void) fprintf( stdout, "bwnfsd: [create_spool] (4.1) Can't reply to RPC call\n");
  1539.                  }
  1540.                  return;
  1541.             }
  1542.        }
  1543.     }
  1544.         if ( i == ips_count)
  1545.     {
  1546.            i = 1;
  1547.            if (!svc_sendreply(transp, xdr_int, &i))
  1548.            {
  1549.               (void) fprintf( stdout, "bwnfsd: [create_spool] (5.2) Can't reply to RPC call\n");
  1550.            }
  1551.            return;
  1552.     }
  1553.     }
  1554.      }
  1555. #ifdef SCO
  1556.  
  1557.      if ( (prpw = getprpwnam(auth_request.username)) == NULL)
  1558.      {
  1559.         if (debugmode)
  1560.           (void) fprintf( stdout, "bwnfsd: [create_spool] getprpwnam failed\n" );
  1561. auth_error:
  1562.         i = 1;
  1563.         if (!svc_sendreply(transp, xdr_int, &i))
  1564.         {
  1565.            (void) fprintf( stdout, "bwnfsd: [create_spool] (5.3) Can't reply to RPC call\n");
  1566.         }
  1567.         return;
  1568.      }
  1569.      if ( prpw->uflg.fg_lock && (prpw->ufld.fd_lock != 0)) goto auth_error;
  1570.      i = prpw->ufld.fd_max_tries;
  1571.      if ( i == 0 ) i = 5;
  1572.      if ( prpw->ufld.fd_nlogins >= (short) i) goto auth_error;
  1573.      prpw->ufld.fd_encrypt[13]='\0';        
  1574.      if ( strcmp(crypt(auth_request.password,prpw->ufld.fd_encrypt),
  1575.             prpw->ufld.fd_encrypt) != 0 ) goto auth_error;
  1576.  
  1577.      if ( (pw = getpwnam(auth_request.username)) == NULL) goto auth_error;
  1578. #else
  1579.      if ( (pw = getpwnam(auth_request.username)) == NULL)
  1580.      {
  1581.         if (debugmode)
  1582.           (void) fprintf( stdout, "bwnfsd: [create_spool] getpwnam failed\n" );
  1583.         i = 1;
  1584.         if (!svc_sendreply(transp, xdr_int, &i))
  1585.         {
  1586.            (void) fprintf( stdout, "bwnfsd: [create_spool] (5.3) Can't reply to RPC call\n");
  1587.         }
  1588.         return;
  1589.      }
  1590. #ifndef SHADOW
  1591.      if ( strcmp(crypt(auth_request.password,pw->pw_passwd),
  1592.             pw->pw_passwd) != 0 )
  1593.      {
  1594.         if (debugmode)
  1595.           (void) fprintf( stdout, "bwnfsd: [create_spool] crypt request failed\n" );
  1596.         i = 1;
  1597.         if (!svc_sendreply(transp, xdr_int, &i))
  1598.         {
  1599.            (void) fprintf( stdout, "bwnfsd: [create_spool] (6) Can't reply to RPC call\n");
  1600.            (void) fflush( stdout );
  1601.            exit(1);
  1602.         }
  1603.         return;
  1604.      }
  1605. #else /* if SHADOW */    /* Use Shadow password facility */
  1606.      if ( (sp = getspnam(auth_request.username)) == NULL)
  1607.      {
  1608.         if (debugmode)
  1609.           (void) fprintf( stdout, "bwnfsd: [create_spool] getspnam request failed\n" );
  1610.         i = 1;
  1611.         if (!svc_sendreply(transp, xdr_int, &i))
  1612.         {
  1613.            (void) fprintf( stdout, "bwnfsd: [create_spool] (5.1) Can't reply to RPC call\n");
  1614.            (void) fflush( stdout );
  1615.            exit(1);
  1616.         }
  1617.         return;
  1618.      }
  1619.  
  1620.      if ( strcmp(crypt(auth_request.password,sp->sp_pwdp),
  1621.             sp->sp_pwdp) != 0 )
  1622.      {
  1623.         if (debugmode)
  1624.           (void) fprintf( stdout, "bwnfsd: [create_spool] crypt request failed\n" );
  1625.         i = 1;
  1626.         if (!svc_sendreply(transp, xdr_int, &i)) {
  1627.            (void) fprintf( stdout, "bwnfsd: [create_spool] (6) Can't reply to RPC call\n");
  1628.            (void) fflush( stdout );
  1629.            exit(1);
  1630.         }
  1631.         return;
  1632.      }
  1633. #endif
  1634. #endif
  1635.      if (auth_request.type == 3)
  1636.      {
  1637.            for ( i = 0; i < num_printers; i++)
  1638.             if( strcmp(printers[i],auth_request.device) == 0)
  1639.                break;
  1640.            if ( i == num_printers)
  1641.            {
  1642.               if (debugmode)
  1643.                 (void) fprintf( stdout, "bwnfsd: [create_spool] Printer %s not found\n",
  1644.                                 auth_request.device );
  1645.               i = 2;
  1646.           if (!svc_sendreply(transp, xdr_int, &i))
  1647.               {
  1648.                 (void) fprintf( stdout, "bwnfsd: [create_spool] (7) Can't reply to RPC call\n");
  1649.               }
  1650.               return;
  1651.            }
  1652. #ifdef SCO
  1653.           if ( !check_access(i,auth_request.username))
  1654.        {
  1655.               if (debugmode)
  1656.                 (void) fprintf( stdout, "bwnfsd: [create_spool] Not authorized for %s\n",
  1657.                                 auth_request.device );
  1658.               i = 1;
  1659.               if (!svc_sendreply(transp, xdr_int, &i)) {
  1660.                  (void) fprintf( stdout, "bwnfsd: [create_spool] (6) Can't reply to RPC call\n");
  1661.                  (void) fflush( stdout );
  1662.                  exit(1);
  1663.               }
  1664.               return;
  1665.        }
  1666. #endif
  1667.       }
  1668.      if (!svc_sendreply(transp, xdr_pw, pw))
  1669.      {
  1670.         (void) fprintf( stdout, "bwnfsd: [create_spool] (8) Can't reply to RPC call\n");
  1671.      }
  1672.      return;
  1673.   case GRP_NAME_TO_NUMB:
  1674.      if (!svc_getargs(transp,xdr_g_string, g_string))
  1675.      {
  1676.         if (debugmode)
  1677.           (void) fprintf( stdout, "bwnfsd: [create_spool] svc_getargs request failed\n" );
  1678.         svcerr_decode(transp);
  1679.     return;
  1680.      }
  1681.      if (!svc_sendreply(transp, xdr_send_gid, g_string))
  1682.      {
  1683.         (void) fprintf( stdout, "bwnfsd: [create_spool] (9) Can't reply to RPC call\n");
  1684.      }
  1685.      return;
  1686.   case GRP_TO_NUMBER:
  1687.      if (!svc_getargs(transp,xdr_ngids, lgids))
  1688.      {
  1689.         if (debugmode)
  1690.           (void) fprintf( stdout, "bwnfsd: [create_spool] svc_getargs request failed\n" );
  1691.         svcerr_decode(transp);
  1692.     return;
  1693.      }
  1694.      if (!svc_sendreply(transp, xdr_send_names, lgids))
  1695.      {
  1696.         (void) fprintf( stdout, "bwnfsd: [create_spool] (10) Can't reply to RPC call\n");
  1697.      }
  1698.      return;
  1699.   case RETURN_HOST:
  1700.      if (!svc_getargs(transp,xdr_int, &r_ip))
  1701.      {
  1702.         if (debugmode)
  1703.           (void) fprintf( stdout, "bwnfsd: [create_spool] svc_getargs request failed\n" );
  1704.         svcerr_decode(transp);
  1705.     return;
  1706.      }
  1707.      if ( r_ip == my_ip)
  1708.     p = hostname;
  1709.      else
  1710.      {
  1711.     struct hostent *h;
  1712.         incomming_ip = ntohl(r_ip);
  1713.     h            = gethostbyaddr((char *) &incomming_ip,4,AF_INET);
  1714.     if ( h == NULL)
  1715.         {
  1716.            (void) sprintf(remote_host,"%u.%u.%u.%u",(incomming_ip ) & 0xff,
  1717.            (incomming_ip >> 8) & 0xff,(incomming_ip >> 16) & 0xff,
  1718.                    (incomming_ip >> 24) & 0xff);
  1719.        p = remote_host;
  1720.         }
  1721.     else
  1722.        p = h->h_name;
  1723.      }
  1724.      if (debugmode)
  1725.        (void) fprintf( stdout, "bwnfsd: [create_spool] remote = %s\n", p );
  1726.  
  1727.      if (!svc_sendreply(transp, xdr_g_string, p))
  1728.         (void) fprintf( stdout, "bwnfsd: [create_spool] (11) Can't reply to RPC call\n");
  1729.      return;
  1730.   case UID_TO_NAME:
  1731.      if (!svc_getargs(transp,xdr_nuids, luids))
  1732.      {
  1733.         if (debugmode)
  1734.           (void) fprintf( stdout, "bwnfsd: [create_spool] svc_getargs failed\n", p );
  1735.         svcerr_decode(transp);
  1736.     return;
  1737.      }
  1738.      if (!svc_sendreply(transp, xdr_send_usernames, luids))
  1739.      {
  1740.         (void) fprintf( stdout, "bwnfsd: [create_spool] (12) Can't reply to RPC call\n");
  1741.      }
  1742.      return;
  1743.   case REMOVE:
  1744.      if (!svc_getargs(transp,xdr_get_lock_name,lock.name))
  1745.      {
  1746.         if (debugmode)
  1747.           (void) fprintf( stdout, "bwnfsd: [create_spool] svc_getargs failed\n");
  1748.         svcerr_decode(transp);
  1749.     return;
  1750.      }
  1751.  
  1752.      process_lock_request((int) rqstp->rq_proc,lock.name,lock.fh,lock.access,
  1753.                lock.mode,lock.offset,lock.length,lock.cookie);
  1754.      if (!svc_sendreply(transp,xdr_void,NULL))
  1755.      {
  1756.         (void) fprintf( stdout, "bwnfsd: [create_spool] (13) Can't reply to RPC call\n");
  1757.      }
  1758.      return;
  1759.   case SHARE:
  1760.   case UNSHARE:
  1761.      if (!svc_getargs(transp,xdr_share,&lock))
  1762.      {
  1763.         if (debugmode)
  1764.           (void) fprintf( stdout, "bwnfsd: [create_spool] svc_getargs failed\n");
  1765.         svcerr_decode(transp);
  1766.     return;
  1767.      }
  1768.      lock.stat = !process_lock_request((int) rqstp->rq_proc,lock.name,lock.fh,
  1769.                           lock.access,lock.mode,lock.offset,lock.length,lock.cookie);
  1770.      if (debugmode)
  1771.      {
  1772.     if ( lock.stat )
  1773.       fprintf( stdout, "bwnfsd: [create_spool] lock status = false\n");
  1774.     else
  1775.       fprintf( stdout, "bwnfsd: [create_spool] lock status = true\n");
  1776.      }
  1777.      if (!svc_sendreply(transp,xdr_shareres,&lock))
  1778.      {
  1779.         (void) fprintf( stdout, "bwnfsd: [create_spool] (14) Can't reply to RPC call\n");
  1780.      }
  1781.      return;
  1782.   case LOCK:
  1783.      lock.stat = svc_getargs(transp,xdr_lock,&lock);
  1784.      goto check_lock;
  1785.   case UNLOCK:
  1786.      lock.stat = svc_getargs(transp,xdr_unlock,&lock);
  1787. check_lock:
  1788.      if (!lock.stat)
  1789.      if (!svc_getargs(transp,xdr_lock,&lock))
  1790.      {
  1791.         svcerr_decode(transp);
  1792.     return;
  1793.      }
  1794.      lock.stat = !process_lock_request((int) rqstp->rq_proc,lock.name,lock.fh,
  1795.                           lock.access,lock.mode,lock.offset,lock.length,lock.cookie);
  1796.      if (debugmode)
  1797.      {
  1798.     if ( lock.stat )
  1799.       fprintf( stdout, "bwnfsd: [create_spool/check_lock] lock status = false\n");
  1800.     else
  1801.       fprintf( stdout, "bwnfsd: [create_spool/check_lock] lock status = true\n");
  1802.      }
  1803.      if (!svc_sendreply(transp,xdr_res,&lock))
  1804.      {
  1805.         (void) fprintf( stdout, "bwnfsd: [create_spool] (15) Can't reply to RPC call\n");
  1806.      }
  1807.      return;
  1808.   default:
  1809.      svcerr_noproc(transp);
  1810.      return;
  1811.   }
  1812. }
  1813.  
  1814.  
  1815.  
  1816. static struct fhstatus {
  1817.      int status;
  1818.      char dir[32];
  1819. } mount_return;
  1820.  
  1821. /*
  1822.     Response from rpc.mountd for mount request of SPOOL directory.
  1823. */
  1824. xdr_fhstatus(xdrsp, fhstat)
  1825.         XDR *xdrsp;
  1826.     struct fhstatus *fhstat;
  1827. {
  1828.    int i;
  1829.  
  1830.    if (debugmode)
  1831.      (void) fprintf( stdout, "bwnfsd: [xdr_fhstatus] called\n" );
  1832.    if (!xdr_int(xdrsp, &fhstat->status)) return(0);
  1833.    if (fhstat->status == 0)
  1834.    {
  1835.       for (i = 0 ; i <32 ; i+=4)
  1836.          if (!xdr_int(xdrsp, &(fhstat->dir[0])+i)) return(0);
  1837.    }
  1838.    if (debugmode > 1)
  1839.      (void) fprintf( stdout, "bwnfsd: [xdr_fhstatus] returns (1)\n" );
  1840.    return(1);
  1841. }
  1842.  
  1843.  
  1844. static struct text_string {
  1845.   int length;
  1846.   char *dir;
  1847. } request_text;
  1848.  
  1849. /*
  1850.     Request to mount SPOOL directory.
  1851. */
  1852. xdr_text(xdrsp, req)
  1853.         XDR *xdrsp;
  1854.     struct text_string *req;
  1855. {
  1856.    if (debugmode)
  1857.      (void) fprintf( stdout, "bwnfsd: [xdr_text] mount request for %s\n", req->dir );
  1858.    if (!xdr_bytes(xdrsp, &req->dir, &req->length,255)) return(0);
  1859.    if (debugmode > 1)
  1860.      (void) fprintf( stdout, "bwnfsd: [xdr_text] returns (1)\n" );
  1861.    return(1);
  1862. }
  1863.  
  1864.  
  1865. /*
  1866.     Use rpc.mountd to determine the fhandle of the spool directory,
  1867.     Can be replaced with extracted code from rpc.mountd.
  1868. */
  1869. int get_mount(dir,directory)
  1870.         char *dir,*directory;
  1871. {
  1872.   struct hostent *hp;
  1873.   struct timeval pentry_timeout, total_timeout;
  1874.   struct sockaddr_in server_addr;
  1875.   int    sock = RPC_ANYSOCK;
  1876.   register CLIENT *client;
  1877.   enum clnt_stat clnt_stat;
  1878.  
  1879.    if (debugmode)
  1880.      (void) fprintf( stdout, "bwnfds: [get_mount] called\n" );
  1881.      if (debugmode > 1)
  1882.        (void) fprintf( stdout, "bwnfsd: [get_mount] dir = %s, directory = %s\n",
  1883.                        dir, directory );
  1884.   request_text.length = strlen(directory);
  1885.   request_text.dir    = directory;
  1886.   if ((hp = gethostbyname(hostname)) == NULL)
  1887.   {
  1888.      (void) fprintf( stdout, "bwnfsd: [get_mount] \42%s\42 is not in the /etc/hosts file.\n", hostname );
  1889.      (void) fprintf( stdout, "bwnfsd:             please entered it and re-run.\n" );
  1890.      (void) fflush( stdout );
  1891.      exit(-1);
  1892.    }
  1893.   pentry_timeout.tv_sec  = 3;
  1894.   pentry_timeout.tv_usec = 0;
  1895.   bcopy(hp->h_addr, (caddr_t) &server_addr.sin_addr,hp->h_length);
  1896.   server_addr.sin_family = AF_INET;
  1897.   server_addr.sin_port   = 0;
  1898.   if ((client = clntudp_create( &server_addr, 100005L, 1L,
  1899.                                 pentry_timeout, &sock)) == NULL)
  1900.   {
  1901.      if (debugmode)
  1902.        (void) fprintf( stdout, "bwnfsd: [get_mount] clntupd_create failed\n" );
  1903.      clnt_pcreateerror("clntudp_create");
  1904.      (void) fflush( stdout );
  1905.      exit(-1);
  1906.   }
  1907.   if ( bindresvport(sock, (struct sockaddr_in *) NULL))
  1908.   {
  1909.     if (debugmode)
  1910.       fprintf( stdout, "bwnfsd: [get_mount] cannot allocate reserved port ... not critical.\n");
  1911.   }
  1912.   client->cl_auth       = authunix_create_default();
  1913.   total_timeout.tv_sec  = 20;
  1914.   total_timeout.tv_usec = 0;
  1915.   clnt_stat             = clnt_call( client, 1L, xdr_text, &request_text,
  1916.                                      xdr_fhstatus, &mount_return,
  1917.                                      total_timeout);
  1918.   if ( clnt_stat != RPC_SUCCESS)
  1919.   {
  1920.     if (debugmode)
  1921.       (void) fprintf( stdout, "bwnfsd: [get_mount] clnt_stat failed\n" );
  1922.     clnt_perror(client,"rpc");
  1923.     (void) fflush( stdout );
  1924.     exit(-1);
  1925.   }
  1926.   auth_destroy( client->cl_auth );
  1927.   clnt_destroy( client );
  1928.   if ( mount_return.status == 0L )
  1929.      bcopy(&mount_return.dir[0],dir,32);
  1930.   if (debugmode)
  1931.     (void) fprintf( stdout, "bwnfsd: [get_mount] returns mount status %u\n",
  1932.                     mount_return.status );
  1933.   return( mount_return.status );
  1934. }
  1935.  
  1936.  
  1937. /*
  1938.     Daemon should be killed with a simple KILL and not KILL -9 so
  1939.     that it may unmap itself
  1940. */
  1941. void die()
  1942. {
  1943. #ifndef LINUX
  1944.   (void) fprintf( stdout, "bwnfsd: [die] Daemon is dying\n\n");
  1945. #endif
  1946.   if (debugmode)
  1947.     (void) fflush( stdout );
  1948.   (void) pmap_unset(BW_NFS_PROGRAM, BW_NFS_VERSION);
  1949.   exit(1);
  1950. }
  1951.  
  1952.  
  1953. main(argc,argv)
  1954.   int argc;
  1955.   char **argv;
  1956. {
  1957.   SVCXPRT *transp;
  1958.   char *p,*prog;
  1959.   int    i;
  1960.   struct hostent *hp;
  1961. #ifdef SCO
  1962.   setluid(0);
  1963.   set_auth_parameters(1,"/");
  1964. #endif
  1965.  
  1966. #ifndef LINUX
  1967.   (void) fprintf( stdout, "BWNFSD Authentication Daemon Vsn 2.3 starting\n\n" );
  1968. #endif
  1969.   prog=argv[0];
  1970.   debugmode = 0;
  1971.   argc--;argv++;
  1972. another:
  1973.   if ((argc > 0) && ( strcmp(*argv,"-A") == 0))
  1974.   {
  1975.      argc--; argv++;
  1976.      A_flag=1;
  1977.      goto another;
  1978.   }
  1979.  
  1980.   if ((argc > 0) && ( strcmp(*argv,"-d") == 0))
  1981.   {
  1982.     debugmode++;
  1983.     argc--; argv++;
  1984.     goto another;
  1985.   }
  1986.   if ((argc > 0) && ( strcmp(*argv,"-s") == 0))
  1987.   {
  1988.      argc--; argv++;
  1989.      if (argc < 2)
  1990.      {
  1991.         (void) fprintf( stdout, "usage : %s [-A] [-d] [-s file] spool_area_mount_point\n", prog );
  1992.         (void) fflush( stdout );
  1993.         exit(1);
  1994.      }
  1995.      (void) read_ips(*argv);
  1996.      s_flag=1;
  1997.      argc--; argv++;
  1998.      goto another;
  1999.   }
  2000.   if (argc != 1)
  2001.   {
  2002.      (void) fprintf(stdout,"usage : %s [-A] [-d] [-s file] spool_area_mount_point\n", prog );
  2003.      (void) fflush( stdout );
  2004.      exit(1);
  2005.   }
  2006.  
  2007.   init_locks();
  2008.   hostname = (char *) malloc(255);
  2009.   (void) gethostname(hostname,255);
  2010.   if ((hp = gethostbyname(hostname)) == NULL)
  2011.   {
  2012.      (void) fprintf( stdout, "bwnfsd: host \42%s\42 is not in the /etc/hosts file\n", hostname );
  2013.      (void) fprintf( stdout, "bwnfsd: Please add it to the file and restart %s\n", prog );
  2014.      (void) fflush( stdout );
  2015.      exit(-1);
  2016.    }
  2017.   bcopy(hp->h_addr, (caddr_t) &my_ip,hp->h_length);
  2018.   if ( get_mount(dir,*argv) !=0 )
  2019.   {
  2020.      (void) fprintf( stdout, "bwnfsd: Spool area mount point %s could not be mounted.\n",  *argv );
  2021.      (void) fprintf( stdout, "bwnfsd: Check that %s is in the /etc/exports file & world-writable\n", *argv );
  2022.      (void) fflush( stdout );
  2023.      exit(1);
  2024.   }
  2025. #ifndef DEBUG
  2026.   if ( fork() != 0 ) exit(0);
  2027. #ifdef SCO
  2028.   for ( i = 0; i < 10; i++);
  2029.      (void) close(i);
  2030.   if ( (  i = open("/dev/null",2) ) < 0) exit(1);
  2031.   dup2(i,0);
  2032.   dup2(i,1);
  2033.   dup2(i,2);
  2034.   close(i);
  2035. #else
  2036.   for ( i = 0; i < 10; i++);
  2037.      (void) close(i);
  2038. /*
  2039.     Disassociate the terminal from the process
  2040. */
  2041.   (void) open("/",0);
  2042.   (void) dup2(0,1);
  2043.   (void) dup2(0,2);
  2044. #ifdef TIOCNOTTY
  2045.   i = open("/dev/tty",2);
  2046.   if ( i >= 0)
  2047.   {
  2048.      (void) ioctl(i, TIOCNOTTY, 0);
  2049.      (void) close(i);
  2050.   }
  2051. #endif
  2052. #endif
  2053. #endif
  2054.  
  2055. #ifdef LINUX
  2056.   (void) setpgrp();
  2057. #else
  2058.   (void) setpgrp(0,0);
  2059. #endif
  2060.   p = strcpy(spool_dir,*argv) + strlen(*argv);
  2061.   if ( *(p-1) == '/')
  2062.     *(--p)='\000';
  2063.   get_printers();
  2064.   get_groups();
  2065.   f.status     = 0;
  2066.   f.dir_size   = 32;
  2067.   f.dir_handle = dir;
  2068.  
  2069.   transp = svcudp_create(RPC_ANYSOCK);
  2070.   if ( transp == NULL)
  2071.   {
  2072.      (void) fprintf( stdout,"bwnfsd: [main] Unable to create an RPC server\n");
  2073.      (void) fflush( stdout );
  2074.      exit(1);
  2075.   }
  2076.   (void) pmap_unset(BW_NFS_PROGRAM, BW_NFS_VERSION);
  2077.   if (!svc_register(transp,BW_NFS_PROGRAM, BW_NFS_VERSION,
  2078.                     create_spool, IPPROTO_UDP))
  2079.   {
  2080.      (void) fprintf( stdout, "bwnfsd: [main] Can't register BW-NFS service\n");
  2081.      (void) fflush( stdout );
  2082.      exit(1);
  2083.   }
  2084.   (void) signal(SIGHUP,die);
  2085.   (void) signal(SIGINT,die);
  2086.   (void) signal(SIGQUIT,die);
  2087. #ifdef SIGABRT
  2088.   (void) signal(SIGABRT,die);
  2089. #endif
  2090.   (void) signal(SIGTERM,die);
  2091. #ifdef SIGCHLD
  2092.   (void) signal(SIGCHLD,free_child);
  2093. #endif
  2094. #ifdef SIGCLD
  2095. #ifdef SCO
  2096.   (void) signal(SIGCLD,SIG_IGN);
  2097. #else
  2098.   (void) signal(SIGCLD,free_child);
  2099. #endif
  2100. #endif
  2101.         svc_run();
  2102.         (void) fprintf( stdout,"bwnfsd: [main] svc_run returned!\n");
  2103.         (void) fflush( stdout );
  2104.         exit(1);
  2105. }
  2106.  
  2107.