home *** CD-ROM | disk | FTP | other *** search
/ Network Support Encyclopedia 96-1 / novell-nsepro-1996-1-cd2.iso / download / netware / lw42n2.exe / BWNFSD.C < prev    next >
C/C++ Source or Header  |  1995-01-11  |  74KB  |  2,803 lines

  1. #define VERSION  "3.2a"
  2. /*
  3.     BWNFSD is an RPC daemon used in conjunction with BWNFS (a client NFS
  4. for DOS based PCs. BWNFSD provides Authentication, Print Spooling,
  5. DOS 3.1 Locking, DOS 3.1 Sharing, GID name mapping, UID name mapping services
  6. for BWNFS and associated applications on the PC. BWNFSD is being used also
  7. by Macintosh NFS clients.
  8.  
  9.     The BWNFSD code is originally copyright Beame & Whiteside Software Ltd.
  10. and now is released to the Public Domain. The intent is that all server vendors
  11. included a version of BWNFSD with their operating system. BWNFSD can run
  12. simultanteously with PCNFSD, but provides more features.
  13.  
  14.     Please send modifications to:
  15.  
  16.         Beame & Whiteside Software, Inc.
  17.         706 Hillsborough St.
  18.         Raleigh, North Carolina
  19.         USA 27603-1655
  20.         +1 (919) 831-8989
  21.         support@bws.com
  22.  
  23.     Please modify by including "ifdefs" for your particular operating
  24. system, with appropriate modifications to the "makefile".
  25.  
  26. MODIFICATION HISTORY
  27. --------------------
  28. 11/11/91 gsw  Added some debug statements
  29. 24/03/92 gsw  Changed SHADOW to SHADW since it conflicted on some SYS-V's
  30. 31/07/92 fjw  Changed printers code to check for abnormal conditions
  31. 31/07/92 fjw  Cleaned up the code and repaired the printer parsing
  32. 01/08/92 fjw  Merged in SVR4 code from Frank Glass (gatech!holos0!fsg)
  33. 31/08/92 cfb  Major changes to support pcnfsdv2-style queues, etc.
  34. 31/08/92 fjw  Changed all the ifdefs around for cleaner code
  35. 31/08/92 fjw  Added user cacheing in authorize code
  36. 08/10/92 fjw  Fixed code relating to printing and debugmode
  37. 05/11/92 fjw  Added some pretty print in debug mode
  38. 14/05/93 fjw  Changed the daemon-detach code to be more like Stevens book
  39. 14/05/93 fjw  Consolidated #defines and added support for Univel and Solaris
  40. 09/02/94 fjw  Changed most of the manifest constant names to assist customisation
  41. 09/02/94 fjw  Added code to allow locks/file/process to be removed
  42. 08/05/94 fjw  Fixed set_auth_parameters() *again* (code got lost somehow)
  43. 08/23/94 cpz  Fixed possible undefined SIGCLD; added conditional for netinet
  44. 08/23/94 cpz  Fix debug write in get_gr_gid; Carl Zwanzig
  45. 09/26/94 dp   Change to the make file for BSDI
  46. 11/25/94 fjw  Add checks for xdr_string overruns, thanks to Paul Freeman
  47. 12/09/94 fjw  Add support for Linux (SYSV_PGRP), thanks to Doug Hester
  48.  
  49. */
  50.  
  51. /*
  52.  *  Uncomment the #define line below only if your system uses a Shadow Password
  53.  *  Database and you have received an "Authorization Error" message after
  54.  *  attempting to Link using a valid username & password combination!
  55.  */
  56.  
  57. #ifndef SHADW
  58. /* #define SHADW */
  59. #endif
  60.  
  61. #define MAX_NUM_PRINTERS 500
  62. #define POLL_INTERVAL 60
  63. #define MAX_NUM_CANCEL_CACHE 10
  64. #define NUM_USER_CACHE 3
  65.  
  66. #include <stdio.h>
  67. #include <sys/types.h>
  68. #include <fcntl.h>
  69. #ifdef FIND_QUEUES_AIX
  70. #include <sys/select.h>
  71. #endif
  72. #include <sys/stat.h>
  73. #include <rpc/rpc.h>
  74. #ifndef INCLUDE_BOGOSITY
  75. #include <rpc/clnt.h>   /* added for svr4 , usually included by <rpc/rpc.h> */
  76. #include <rpc/svc.h>
  77. #endif
  78. #include <errno.h>
  79. #include <sys/socket.h>
  80. #include <sys/param.h>
  81. #include <sys/time.h>
  82. #include <sys/ioctl.h>
  83. #include <ctype.h>
  84. #include <arpa/inet.h>
  85. #include <netdb.h>
  86. #include <pwd.h>
  87. #include <signal.h>
  88. #include <grp.h>
  89. #include <string.h>
  90.  
  91. #ifndef DONT_USE_NETINET_IN
  92. #include <netinet/in.h>   /* This is problematic on some systems, required on others */
  93. #endif
  94.  
  95. #ifdef USE_BCOPY
  96. #define memcmp(a,b,c) bcmp((b),(a),(c))
  97. #define memcpy(a,b,c) bcopy((b),(a),(c))
  98. #else
  99. #include <memory.h>
  100. #endif
  101.  
  102. #ifdef SHADW
  103. #include <shadow.h>
  104. #endif
  105.  
  106. #ifdef SGI
  107. extern struct group *getgrent();
  108. #endif
  109.  
  110. char *crypt();
  111. char *my_strdup();
  112. void free_printer();
  113. void get_printers();
  114.  
  115. #ifdef INT_SIG
  116. #define Void int
  117. #define Return return(0)
  118. #else
  119. #define Void void
  120. #define Return return
  121. #endif
  122.  
  123. #ifdef WINNFS
  124. #include <tiuser.h>
  125. #endif
  126.  
  127. #ifdef FIND_QUEUES_SVR4
  128. #define ALLOW 0
  129. #define DENY  1
  130. #define CLASS 2
  131.  
  132. struct {
  133.     int access;
  134.     int count;
  135.     union {
  136.         char **users;
  137.         int  *printers;
  138.     } n;
  139. } printer_access[MAX_NUM_PRINTERS];
  140. #endif
  141.  
  142. #define BW_NFS_PROGRAM 0x2f00dbadL
  143. #define BW_NFS_VERSION 1L
  144.  
  145. #define SPOOL_INQUIRE  1L       /* Return fhandle of spool directory */
  146. #define SPOOL_FILE     2L       /* Spool file */
  147. #define AUTHORIZE      3L       /* Authorize and return UID and GIDs (max 16) */
  148. #define GRP_NAME_TO_NUMB 4L     /* Convert group name to number */
  149. #define GRP_TO_NUMBER  5L       /* Convert group number(s) to name(s) */
  150. #define RETURN_HOST    6L       /* Convert IP to hostname */
  151. #define UID_TO_NAME    7L       /* Convert UID(s) to name(s) */
  152. #define NAME_TO_UID    8L       /* Convert name(s) to UID(s)  L. Yen */
  153. #define SHARE         20L       /* DOS 3.1 Share function */
  154. #define UNSHARE       21L       /* DOS 3.1 UnShare function */
  155. #define LOCK          22L       /* DOS 3.1 Lock request */
  156. #define REMOVE        23L       /* Remove all locks/shares for PC */
  157. #define UNLOCK        24L       /* DOS 3.1 Unlock request */
  158. #define GET_PRINTERS  30L       /* Get a list of printers */
  159. #define GET_PRINTQ    31L       /* Get print queue entries and status */
  160. #define CANCEL_PRJOB  32L       /* Cancel a print job */
  161. #define ZAP_LOCKS    105L       /* Remove locks on file by process */
  162.  
  163. #define NUSRS  10               /* Maximum names to convert */
  164.  
  165. #define WNPRQ_ACTIVE    0
  166. #define WNPRQ_PAUSE     1
  167. #define WNPRQ_ERROR     2
  168. #define WNPRQ_PENDING   3
  169. #define WNPRQ_PROBLEM   4
  170. #define WN_SUCCESS      0
  171. #define WN_BAD_QUEUE    0x43
  172.  
  173. static  char    dir[32],g_string[32];
  174. static  char    spool_dir[132], file[256], file1[256];
  175. static  char    remote_host[16];
  176. static  int     num_printers;
  177. static  char    printer[12];
  178. static  char    *jobname;
  179. static  char    file_name[9];
  180. static  char    *hostname,*p;
  181. static  int     extension, lgids[NGRPS+1];
  182. static  int     luids[NUSRS+1];
  183. static  int     A_flag=0, s_flag=0, do_print;
  184. int debugmode;
  185. static  unsigned long my_ip;
  186. static  unsigned long incomming_ip;
  187.  
  188. struct queueentry {
  189.     int jobid;
  190.     char *username;
  191.     char *params;
  192.     int queueposition;
  193.     int jobstatus;
  194.     unsigned long timesubmitted;
  195.     unsigned long size;
  196.     int copies;
  197.     char *jobcomment;
  198.     struct queueentry *next;
  199. };
  200.  
  201. struct printertype {
  202.     char *queuename;
  203.     char *queuecomment;
  204.     int queuestatus;
  205.     int numphysicalprinters;
  206.     unsigned long lasttime;
  207.     struct queueentry *head;
  208. } printers[MAX_NUM_PRINTERS];
  209.  
  210. static struct mm_ips {          /* Valid hosts to authenticate for */
  211.     char          type;
  212.     unsigned long ip;
  213.     unsigned long mask;
  214.     unsigned long redirect_ip;
  215. } **ips;
  216.  
  217. static struct mm_uids {         /* Cache of uid to name translation */
  218.     int     mm_uid;
  219.     char    *mm_username;
  220. } **uds;
  221.  
  222. static struct mm_gidss {        /* Cache of uid and associated gids */
  223.     int mm_uid;
  224.     int mm_gid;
  225.     int mm_gid_count;
  226.     int mm_gids[NGRPS];
  227. } **gds;
  228.  
  229. static int gids_count=0, uids_count=0;
  230. static int ips_count=0;
  231.  
  232. static struct locking {
  233.     unsigned long   lockowner;      /* 4 bytes */
  234.     unsigned long   cookie;         /* 4 bytes */
  235.     char            name[17];       /* 16 character name */
  236.     char            fh[32];         /* 32 bytes */
  237.     int             mode;
  238.     int             access;
  239.     unsigned long   offset;
  240.     unsigned long   length;
  241.     int             stat;
  242.     int             sequence;
  243. } lock = { 0 };
  244.  
  245. static struct printqs {
  246.     char queuename[32];
  247.     char username[32];
  248.     int printer_number;
  249. } printq;
  250.  
  251. static struct cancaches {
  252.     char queuename[32];
  253.     char username[32];
  254.     int jobid;
  255.     int response;
  256. } cancache[MAX_NUM_CANCEL_CACHE] = { 0 };
  257.  
  258. int current_cache=0;
  259.  
  260. int
  261. my_strnicmp(p1, p2, num)
  262.     char *p1, *p2;
  263.     int num;
  264. {
  265. char c, d;
  266.  
  267.     for ( ; num>0; num--) {
  268.         c = *p1++;
  269.         d = *p2++;
  270.         c = islower(c)?toupper(c):c;
  271.         d = islower(d)?toupper(d):d;
  272.         if (c != d)
  273.             return(1);
  274.     }
  275.     return(0);
  276. }
  277.  
  278. #ifdef CHECK_PRINTER_ACCESS
  279. int
  280. check_access_printer(pn,name)
  281.     int pn;
  282.     char *name;
  283. {
  284. int i;
  285. char **p;
  286.  
  287.     if (debugmode)
  288.         fprintf(stdout, "bwnfsd: [check_access_printer] pn = %d, name = %s\n", pn, name);
  289.  
  290.     if (printer_access[pn].count == -1) {
  291.         if (debugmode)
  292.             fprintf(stdout, "bwnfsd: [check_access_printer] deny all requests\n");
  293.         return(0);                                   /* Deny all */
  294.     }
  295.     p = printer_access[pn].n.users;
  296.     for (i=0; i<printer_access[pn].count; i++) {
  297.         if (strcmp(*p++,name) == 0) {
  298.             if (debugmode)
  299.                 fprintf(stdout, "bwnfsd: [check_access_printer] request %s\n", printer_access[pn].access==ALLOW?"allowed":"denied");
  300.             return(printer_access[pn].access == ALLOW);
  301.         }
  302.     }
  303.     if (debugmode)
  304.         fprintf(stdout, "bwnfsd: [check_access_printer] request %s\n", printer_access[pn].access==DENY?"allowed":"denied");
  305.     return(printer_access[pn].access == DENY);
  306. }
  307.  
  308. int
  309. check_access(pn, name)
  310.     int pn;
  311.     char *name;
  312. {
  313. int i;
  314. int *pi;
  315.  
  316.     if (debugmode)
  317.         fprintf(stdout, "bwnfsd: [check_access] pn = %d, name = %s\n", pn, name);
  318.  
  319.     if (printer_access[pn].access != CLASS)
  320.         return(check_access_printer(pn,name));
  321.     pi = printer_access[pn].n.printers;
  322.     for (i=0; i<printer_access[pn].count; i++)
  323.         if (check_access_printer(*pi++,name)) {
  324.             if (debugmode)
  325.                 fprintf(stdout, "bwnfsd: [check_access] returns 1\n");
  326.             return(1);
  327.         }
  328.     if (debugmode)
  329.         fprintf(stdout, "bwnfsd: [check_access] returns 0\n");
  330.     return(0);
  331. }
  332. #endif
  333.  
  334. Void
  335. clear(unused)
  336.     int unused;
  337. {
  338. int i;
  339.  
  340.     if (debugmode)
  341.         fprintf(stdout, "bwnfsd: [clear]\n");
  342.     for (i=0; i<uids_count; i++) {
  343.         free((*(uds+i))->mm_username);
  344.         free(*(uds+i));
  345.     }
  346.     if (uids_count > 0) {
  347.         free(uds);
  348.         uids_count = 0;
  349.     }
  350.     endpwent();
  351.     for (i=0; i<gids_count; i++)
  352.         free(*(gds+i));
  353.     if (gids_count > 0) {
  354.         free(gds);
  355.         gids_count = 0;
  356.     }
  357.     endgrent();
  358.     for (i=0; i<num_printers; i++) {
  359.         free_printer(i);
  360.         free(printers[i].queuename);
  361.         if (printers[i].queuecomment != NULL)
  362.             free(printers[i].queuecomment);
  363.     }
  364.     get_printers();
  365.     (void) signal(SIGHUP, clear);
  366.     Return;
  367. }
  368.  
  369. Void
  370. free_child(unused)
  371.     int unused;
  372. {
  373.     if (debugmode)
  374.         fprintf(stdout, "bwnfsd: [free_child] called\n");
  375.  
  376.     (void) wait(NULL);
  377. #ifdef SIGCHLD
  378.     (void) signal(SIGCHLD,free_child);
  379. #endif
  380. #ifdef SIGCLD
  381.     (void) signal(SIGCLD,free_child);
  382. #endif
  383.     Return;
  384. }
  385.  
  386. void
  387. strlwr(p)
  388.     char *p;
  389. {
  390.     do {
  391.         if ((*p >= 'A') && (*p <= 'Z'))
  392.             *p += 'a'-'A';
  393.     } while (*(++p) != '\0');
  394. }
  395.  
  396. void
  397. getmask(ip,mask)
  398.     unsigned long *ip, *mask;
  399. {
  400.     if (*ip == 0L)
  401.         *mask = 0L;
  402.     else if (*ip <= 0xffL) {
  403.         *ip <<= 24;
  404.         *mask = 0xff000000L;
  405.     } else if (*ip <= 0xffffL) {
  406.         *ip <<= 16;
  407.         *mask = 0xffff0000L;
  408.     } else if (*ip <= 0xffffffL) {
  409.         *ip <<= 8;
  410.         *mask = 0xffffff00L;
  411.     } else
  412.         *mask = 0xffffffffL;
  413. }
  414.  
  415. unsigned long
  416. my_inet_addr(cp)
  417.     char *cp;
  418. {
  419. static union {
  420.      unsigned long inn;
  421.      struct {
  422.          unsigned char b1, b2, b3, b4;
  423.      } i;
  424. } in;
  425. int b1, b2, b3, b4;
  426.  
  427.     b1 = b2 = b3 = b4 = -1;
  428.     if (sscanf(cp,"%d.%d.%d.%d", &b1, &b2, &b3, &b4) == -1)
  429.         return(~0L);
  430.     if (b4 == -1) {
  431.         b4 = b3;
  432.         b3 = b2;
  433.         b2 = 0;
  434.     }
  435.     if (b4 == -1) {
  436.         b4 = b3;
  437.         b3 = 0;
  438.     }
  439.     if (((unsigned) b1 > 255) || ((unsigned) b2 > 255)
  440.       ||((unsigned) b3 > 255) || ((unsigned) b4 > 255))
  441.         return(~0L);
  442.     in.i.b1 = (unsigned char) b1;
  443.     in.i.b2 = (unsigned char) b2;
  444.     in.i.b3 = (unsigned char) b3;
  445.     in.i.b4 = (unsigned char) b4;
  446.     return(ntohl(in.inn));
  447. }
  448.  
  449. /*
  450.  *  For -s parameter, returns IP addresses and the associated mask to determine
  451.  *  if the IP address of the destination machine/network is matches an entry
  452.  *  in the -s file.
  453.  */
  454. int
  455. convert_ip(s,ip,mask)
  456.     char *s;
  457.     unsigned long *ip, *mask;
  458. {
  459. unsigned long ia, lip, lmask;
  460. struct hostent *he;
  461. struct netent *ne;
  462.  
  463.     if (debugmode)
  464.         fprintf(stdout, "bwnfsd: [convert_ip] s = %s\n", s);
  465.  
  466.     if ((ia=inet_network(s)) != (~0L)) {
  467.         lip = ia;
  468.         getmask(&lip,&lmask);
  469.     } else {
  470.         if ((ia=my_inet_addr(s)) != (~0L)) {
  471.             lip = ia;
  472.             lmask = 0xffffffffL;
  473.         } else {
  474.             if ((ne=getnetbyname(s)) != NULL) {
  475.                 lip = ne->n_net;
  476.                 getmask(&lip,&lmask);
  477.             } else {
  478.                 if ((he=gethostbyname(s)) != NULL) {
  479.                     lip = * (unsigned long *) he->h_addr;
  480.                     lmask = 0xffffffffL;
  481.                 } else {
  482.                     if (debugmode)
  483.                         fprintf(stdout, "bwnfsd: [convert_ip] returns 0\n");
  484.                     return(0);
  485.                 }
  486.             }
  487.         }
  488.     }
  489.     *ip = lip;
  490.     if (mask != NULL)
  491.         *mask = lmask;
  492.     if (debugmode)
  493.         fprintf(stdout, "bwnfsd: [convert_ip] (1) ip = %lu, mask = %lu\n", ip, mask);
  494.     return(1);
  495. }
  496.  
  497. /*
  498.  *       Read the -s file which lists rules for which hosts can be
  499.  *       authenticated. Each line is converted to a IP address and mask. Any
  500.  *       incoming address is ANDed with the mask and compared to IP address,
  501.  *       if it matches, the action associated with the line is taken.
  502.  *
  503.  *       Valid actions:
  504.  *               "+" - Perform Validatation check
  505.  *               "-" - Return Authorization error
  506.  *               "=" - Tell client to attempt Authorization at new address
  507.  */
  508. void
  509. read_ips(file)
  510.     char *file;
  511. {
  512. FILE *f;
  513. char s1[255], s2[255], line[255], type;
  514. int i;
  515. unsigned long ip, mask, redirect_ip;
  516.  
  517.     if (debugmode)
  518.         fprintf(stdout, "bwnfsd: [read_ips] file = %s\n", file);
  519.  
  520.     if ((f=fopen(file,"r")) == NULL) {
  521.         fprintf(stdout, "bwnfsd: [read_ips] \"%s\" file not found.\n",file);
  522.         fflush(stdout);
  523.         exit(1);
  524.     }
  525.  
  526.     ips = (struct mm_ips **) malloc(1);
  527.     while (fgets(line,sizeof(line)-1,f) != NULL) {
  528.         if ((type=line[0]) != '#') {
  529.             i = sscanf(&line[1],"%s %s",s1,s2);
  530.             if (debugmode)
  531.                 fprintf(stdout, "bwnfsd: [read_ips] parsing <%s>\n", &line[1]);
  532.  
  533.             if ((i == EOF) || (i == 0) || (i > 2) || ((type != '+') &&
  534.                 (type != '-') && (type != '=')) || ((type == '=') &&
  535.                 (i != 2)) || ((type != '=') && (i != 1))) {
  536.                 fprintf(stdout, "bwnfsd: [read_ips] syntax error, line ignored : %s",line);
  537.             } else {
  538.                 if (!convert_ip(s1,&ip,&mask)) {
  539.                     fprintf(stdout, "bwnfsd: [read_ips] \"%s\" invalid address.\n",s1);
  540.                     continue;
  541.                 }
  542.                 if (i == 2)
  543.                     if (!convert_ip(s2, &redirect_ip, NULL)) {
  544.                            fprintf(stdout, "bwnfsd: [read_ips] \42%s\42 invalid address.\n",s1);
  545.                            continue;
  546.                     }
  547.                 ips = (struct mm_ips **) realloc(ips,sizeof(ips)*(ips_count+1));
  548.                 *(ips+ips_count) = (struct mm_ips *) malloc(sizeof(struct mm_ips));
  549.                 (*(ips+ips_count))->type        = type;
  550.                 (*(ips+ips_count))->ip          = ip;
  551.                 (*(ips+ips_count))->mask        = mask;
  552.                 (*(ips+ips_count))->redirect_ip = redirect_ip;
  553.                 ips_count++;
  554.                }
  555.         }
  556.     }
  557.     fclose(f);
  558.     if (debugmode)
  559.         fprintf(stdout, "bwnfsd: [read_ips] exiting with %u values\n", ips_count);
  560. }
  561.  
  562. /*
  563.  *       Add UID to USERNAME translation to cache
  564.  */
  565. void
  566. add_uid(uid,username)
  567.     int     uid;
  568.     char    *username;
  569. {
  570.     if (debugmode)
  571.         fprintf(stdout, "bwnfsd: [add_uid] uid <%d>, name <%s>\n", uid, username);
  572.     if (uids_count++ == 0)
  573.         uds = (struct mm_uids **) malloc(1);
  574.  
  575.     uds                                = (struct mm_uids **) realloc(uds,sizeof(uds)*uids_count);
  576.     (*(uds+uids_count-1))              = (struct mm_uids *) malloc(sizeof(struct mm_uids));
  577.     (*(uds+uids_count-1))->mm_uid      = uid;
  578.     (*(uds+uids_count-1))->mm_username = (char *) malloc(strlen(username)+1);
  579.     (void) strcpy((*(uds+uids_count-1))->mm_username,username);
  580. }
  581.  
  582. /*
  583.  *       Lookup USERNAME given a UID, also add translation to cache
  584.  */
  585. char *
  586. get_ui_name(uid)
  587.     int     uid;
  588. {
  589. struct passwd *pww;
  590. int i;
  591. static char ui[32];
  592.  
  593.     if (debugmode)
  594.         fprintf(stdout, "bwnfsd: [get_ui_name] uid <%u>\n", uid);
  595.  
  596.     for (i=0; i<uids_count; i++)
  597.         if ((*(uds+i))->mm_uid == uid)
  598.             return((*(uds+i))->mm_username);
  599.     if ((pww=getpwuid(uid)) == NULL) {
  600.         sprintf(ui,"%d",uid);
  601.         if (debugmode)
  602.             fprintf(stdout, "bwnfsd: [get_ui_name] getpwuid returned %s\n", ui);
  603.         return(ui);
  604.     }
  605.     add_uid(uid,pww->pw_name);
  606.     if (debugmode)
  607.         fprintf(stdout, "bwnfsd: [get_ui_name] returns %s\n", pww->pw_name);
  608.     return(pww->pw_name);
  609. }
  610.  
  611. /*
  612.  *       Given a UID, GID and USERNAME, create a list of GIDs associated
  613.  *       with the UID, a maximum of NGRPS GIDS are used.
  614.  */
  615. void
  616. fill_gid(gd,uid,gid,username)
  617.     struct mm_gidss *gd;
  618.     int     uid,gid;
  619.     char    *username;
  620. {
  621. struct group *gr;
  622. struct group *getgrent();
  623. char   **p;
  624. int    flag;
  625.  
  626.     add_uid(uid,username);
  627.     if (debugmode)
  628.         fprintf(stdout, "bwnfsd: [fill_gid] uid = %u, gid = %u, user = %s\n", uid, gid, username);
  629.     flag             = 0;
  630.     gd->mm_uid       = uid;
  631.     gd->mm_gid       = gid;
  632.     gd->mm_gid_count = 0;
  633.     (void) setgrent();
  634.     while ((gr=getgrent()) != NULL) {
  635.         p = gr->gr_mem;
  636.         while (((*p) != NULL) && (gd->mm_gid_count < NGRPS)) {
  637.             if (strcmp((*p),username) == 0) {
  638.                 gd->mm_gids[gd->mm_gid_count++] = gr->gr_gid;
  639.                 if (gr->gr_gid == gid)
  640.                     flag = 1;
  641.                 break;
  642.             }
  643.             p++;
  644.         }
  645.     }
  646.     if ((flag == 0) && (gd->mm_gid_count < NGRPS))
  647.         gd->mm_gids[gd->mm_gid_count++] = gid;
  648.     (void) endgrent();
  649. }
  650.  
  651. /*
  652.  *       Return a list of GIDs for a given UID. The cache of GIDS/UID is
  653.  *       updated and used.
  654.  */
  655. struct mm_gidss *
  656. get_gids(uid,gid,username)
  657.     int uid,gid;
  658.     char *username;
  659. {
  660. int i;
  661.  
  662.     if (debugmode)
  663.         fprintf(stdout, "bwnfsd: [mm_gidss] uid = %u, gid = %u, name = %s\n", uid, gid, username);
  664.  
  665.     for (i=0; i<gids_count; i++)
  666.         if ((*(gds+i))->mm_uid == uid) {
  667.             if (debugmode)
  668.                 fprintf(stdout, "bwnfsd: [mm_gidss] gids_count = %u\n", gids_count);
  669.             return(*(gds+i));
  670.         }
  671.  
  672.     if (gids_count++ == 0)
  673.         gds = (struct mm_gidss **) malloc(1);
  674.  
  675.     gds = (struct mm_gidss **) realloc(gds,sizeof(gds)*gids_count);
  676.     (*(gds+gids_count-1)) = (struct mm_gidss *) malloc(sizeof(struct mm_gidss));
  677.     (void) fill_gid((*(gds+gids_count-1)), uid, gid, username);
  678.     if (debugmode)
  679.         fprintf(stdout, "bwnfsd: [mm_gidss] gids_count = %u\n", gids_count);
  680.     return(*(gds+gids_count-1));
  681. }
  682.  
  683. static struct my_groups {
  684.     int my_gid;
  685.     char    *my_name;
  686. } **g;
  687.  
  688. static int group_count=0;
  689.  
  690. /*
  691.  *       Return the text name of a GID, if none is found, then the GID
  692.  *       is convert to a text number.
  693.  */
  694. char *
  695. get_gr_name(gid)
  696.     int     gid;
  697. {
  698. static char gd[32];
  699. int i;
  700.  
  701.     if (debugmode)
  702.         fprintf(stdout, "bwnfsd: [get_gr_name] for gid %u\n", gid);
  703.  
  704.     for (i=0; i<group_count; i++)
  705.         if ((*(g+i))->my_gid == gid) {
  706.             if (debugmode)
  707.                 fprintf(stdout, "bwnfsd: [get_gr_name] returns %s\n", ((*(g+i))->my_name));
  708.             return ((*(g+i))->my_name);
  709.         }
  710.     sprintf(gd,"%d",gid);
  711.     if (debugmode)
  712.         fprintf(stdout, "bwnfsd: [get_gr_name] returns %s\n", gd);
  713.     return(gd);
  714. }
  715.  
  716. /*
  717.  *       Given a group name, return the GID associated with it.
  718.  */
  719. int *
  720. get_gr_gid(name)
  721.     char *name;
  722. {
  723. int i;
  724.  
  725.     if (debugmode)
  726.         fprintf(stdout, "bwnfsd: [get_gr_gid] for %s\n", name);
  727.     for (i=0; i<group_count; i++)
  728.         if (strcmp((*(g+i))->my_name,name) == 0) {
  729.             if (debugmode)
  730.                 fprintf(stdout, "bwnfsd: [get_gr_gid] returns %d\n", (*(g+i))->my_gid);
  731.             return(&(*(g+i))->my_gid);
  732.         }
  733.     if (debugmode)
  734.         fprintf(stdout, "bwnfsd: [get_gr_gid] returns NULL\n");
  735.     return (NULL);
  736. }
  737.  
  738. /*
  739.  *       Cache a list of all group names and their associated GIDS.
  740.  */
  741. void
  742. get_groups()
  743. {
  744. struct group *gr;
  745. struct group *getgrent();
  746.  
  747.     if (debugmode)
  748.         fprintf(stdout, "bwnfsd: [get_groups] called\n");
  749.  
  750.     g = (struct my_groups **) malloc(1);
  751.     (void) setgrent();
  752.     while ((gr=getgrent()) != NULL) {
  753.         group_count++;
  754.         g = (struct my_groups **) realloc(g,sizeof(g)*group_count);
  755.         (*(g+group_count-1)) = (struct my_groups *) malloc(sizeof(struct my_groups));
  756.         (*(g+group_count-1))->my_name = (char *) malloc(strlen(gr->gr_name)+1);
  757.  
  758.         (void) strcpy((*(g+group_count-1))->my_name,gr->gr_name);
  759.         (*(g+group_count-1))->my_gid = gr->gr_gid;
  760.     }
  761.     (void) endgrent();
  762. }
  763.  
  764. #ifdef FIND_QUEUES_SVR4
  765. void
  766. get_class_list(char *name, int pn)
  767. {
  768. FILE *f;
  769. char line[128];
  770. char file_name[64];
  771. int i;
  772.  
  773.     if (debugmode)
  774.         fprintf(stdout, "bwnfsd: [get_class_list] name = %s, pn = %u\n", name, pn);
  775.     printer_access[pn].access     = CLASS;
  776.     printer_access[pn].n.printers = NULL;
  777.     printer_access[pn].count      = 0;
  778.     sprintf(file_name,"/usr/spool/lp/admins/lp/classes/%s",name);
  779.  
  780.     if ((f=fopen(file_name,"r")) == NULL) {
  781.         if (debugmode)
  782.             fprintf(stdout, "bwnfsd: [get_class_list] open file %s returned NULL\n", file_name);
  783.         return;
  784.     }
  785.     while (fgets(line,128,f) != NULL) {
  786.         *(line+strlen(line)-1) = '\0';
  787.         for (i=0; i<pn; i++)
  788.             if (strcmp(line,printers[i].queuename) == 0) {
  789.                 if (printer_access[pn].count++ == 0)
  790.                     printer_access[pn].n.printers = (int *) malloc(sizeof(int));
  791.                 else
  792.                     printer_access[pn].n.printers = (int *) realloc(printer_access[pn].n.printers,printer_access[pn].count * sizeof(int));
  793.                 *(printer_access[pn].n.printers+printer_access[pn].count-1) = i;
  794.                 break;
  795.             }
  796.     }
  797.     fclose(f);
  798. }
  799.  
  800.  
  801. void
  802. get_access(char *name, int pn)
  803. {
  804. FILE *f;
  805. char line[128];
  806. char file_name[64];
  807. char **p;
  808. int i;
  809.  
  810.     if (debugmode)
  811.         fprintf(stdout, "bwnfsd: [get_access] name = %s, pn = %u\n", name, pn);
  812.     printer_access[pn].access  = ALLOW;
  813.     printer_access[pn].n.users = NULL;
  814.     printer_access[pn].count   = 0;
  815.     sprintf(file_name,"/usr/spool/lp/admins/lp/printers/%s/users.allow",name);
  816.     if ((f=fopen(file_name,"r")) != NULL) {
  817.         if (debugmode)
  818.             fprintf(stdout, "bwnfsd: [get_access] reading %s\n", file_name);
  819.         while (fgets(line,128,f) != NULL) {
  820.             *(line+strlen(line)-1) = '\0';
  821.             if ((strcmp(line,"any") == 0) ||
  822.                 (strcmp(line,"all") == 0) ||
  823.                 (strcmp(line,"all!all") == 0)) {
  824.                 printer_access[pn].n.users = NULL;
  825.                 printer_access[pn].count = 0;
  826.                 break;
  827.             }
  828.             if (printer_access[pn].count++ == 0)
  829.                 printer_access[pn].n.users = (char **) malloc(sizeof(char**));
  830.             else
  831.                 printer_access[pn].n.users = (char **) realloc(printer_access[pn].n.users,printer_access[pn].count * sizeof(char**));
  832.             *(printer_access[pn].n.users+printer_access[pn].count-1) = strdup(line);
  833.         }
  834.         fclose(f);
  835.         if (printer_access[pn].count != 0) {
  836.             if (debugmode) {
  837.                 fprintf(stdout, "bwnfsd: [get_access] access count = %u\nbwnfsd: [get_access] Allowed users:\n", printer_access[pn].count);
  838.                 p = printer_access[pn].n.users;
  839.                 for (i=0; i<printer_access[pn].count; i++)
  840.                     fprintf(stdout, "bwnfsd: [get_access]               %s\n", *p++);
  841.             }
  842.             return;
  843.         }
  844.     } else {
  845.         if (debugmode)
  846.             fprintf(stdout, "bwnfsd: [get_access] unable to open %s\n", file_name);
  847.     }
  848.     printer_access[pn].access = DENY;
  849.     sprintf(file_name,"/usr/spool/lp/admins/lp/printers/%s/users.deny",name);
  850.     if ((f=fopen(file_name,"r")) != NULL) {
  851.         while (fgets(line,128,f) != NULL) {
  852.             *(line+strlen(line)-1) = '\0';
  853.             if ((strcmp(line,"any") == 0) || (strcmp(line,"all") == 0)) {
  854.                 printer_access[pn].n.users = NULL;
  855.                 printer_access[pn].count   = -1;
  856.                 break;
  857.             }
  858.             if (printer_access[pn].count++ == 0)
  859.                 printer_access[pn].n.users = (char **) malloc(sizeof(char**));
  860.             else
  861.                 printer_access[pn].n.users = (char **) realloc(printer_access[pn].n.users,printer_access[pn].count * sizeof(char**));
  862.             *(printer_access[pn].n.users+printer_access[pn].count-1) = strdup(line);
  863.         }
  864.         fclose(f);
  865.         if (printer_access[pn].count != 0)
  866.             if (debugmode) {
  867.                 fprintf(stdout, "bwnfsd: [get_access] access count = %u\nbwnfsd: [get_access] Denied users:\n", printer_access[pn].count);
  868.                 p = printer_access[pn].n.users;
  869.                 for (i=0; i<printer_access[pn].count; i++)
  870.                     fprintf(stdout, "bwnfsd: [get_access]               %s\n", *p++);
  871.             }
  872.     } else {
  873.         if (debugmode)
  874.             fprintf(stdout, "bwnfsd: [get_access] unable to open %s\n", file_name);
  875.     }
  876. }
  877.  
  878.  
  879. void
  880. get_printer_list(status_file, type)
  881. char *status_file;
  882. int  type;
  883. {
  884. FILE *f;
  885. char line[128],name[32];
  886. int  i;
  887.  
  888.     if (debugmode)
  889.         fprintf(stdout, "bwnfsd: [get_printer_list] file = %s, type = %u\n", status_file, type);
  890.     if ((f=fopen(status_file,"r")) == NULL) {
  891.         if (debugmode)
  892.             fprintf(stdout, "bwnfsd: [get_printer_list] unable to open %s\n", status_file);
  893.         return;
  894.     }
  895.     while (fgets(line,128,f) != NULL)
  896.         if (strncmp(line,"=====",5) == 0) {
  897.             if (fgets(name,32,f) == NULL)
  898.                 break;
  899.             *(name+strlen(name)-1) = '\0';
  900.             if (fgets(line,128,f) == NULL)
  901.                 break;
  902.             *(line+strlen(line)-1) = '\0';
  903.             if (debugmode)
  904.                 fprintf(stdout, "bwnfsd: [get_printer_list] name = %s, line = %s\n", name, line);
  905.             for (i=0; i<(int)strlen(line); i++)
  906.                 if (strncmp(&line[i],"accepting",9) == 0)
  907.                     break;
  908.             if (i == strlen(line))
  909.                 continue;
  910.             if (strlen(name) > 11) {
  911.                 fprintf(stdout, "bwnfsd: [get_printer_list] Printer name \"%s\" exceeds 11 characters; not available for linking\n", name);
  912.                 continue;
  913.             }
  914.             if (num_printers >= MAX_NUM_PRINTERS) {
  915.                 if (debugmode)
  916.                     fprintf(stdout, "bwnfsd: [get_printer_list] Max number of printers (%d) exceeded.  Recompile with larger value\n", MAX_NUM_PRINTERS);
  917.                 break;
  918.             }
  919.             printers[num_printers].queuename = strdup(name);
  920.             printers[num_printers].queuecomment = NULL;
  921.             if (type == 0)
  922.                 get_access(name,num_printers++);
  923.             else
  924.                 get_class_list(name,num_printers++);
  925.         }
  926.     fclose(f);
  927. }
  928. #endif
  929.  
  930. /*
  931.  *       Cache a list of available printers, BSD code searchs the /etc/printcap
  932.  *       file.  Creating a dummy /etc/printcap can also work.
  933.  */
  934. void
  935. get_printers()
  936. {
  937. #ifndef FIND_QUEUES_SVR4
  938. static char line[1024];
  939. #ifdef FIND_QUEUES_AIX
  940. static char stanza[255];
  941. #endif
  942. char *p, *p1, *end;
  943. FILE *f;
  944. int start;
  945. #endif
  946. int i;
  947.  
  948.     if (debugmode)
  949.         fprintf(stdout, "bwnfsd: [get_printers] called\n");
  950.  
  951.     num_printers = 0;
  952. #ifdef FIND_QUEUES_SVR4
  953.     get_printer_list("/usr/spool/lp/system/pstatus",0);
  954.     get_printer_list("/usr/spool/lp/system/cstatus",1);
  955. #else
  956. #ifdef FIND_QUEUES_AIX
  957.     if ((f=fopen("/etc/qconfig","r")) == NULL) {
  958.         fprintf(stdout, "bwnfsd: File /etc/qconfig was not found.\n");
  959.         fprintf(stdout, "        No printers are available for use.\n");
  960.         fflush(stdout);
  961.         return;
  962.     }
  963.  
  964.     stanza[0] = '\0';
  965.     while (fgets(line,sizeof(line)-1,f) != NULL) {
  966.         line[sizeof(line)-1] = '\0';
  967.         for (p=line; isspace(*p); )
  968.             p++;
  969.         if (*p == '*')
  970.             continue;
  971.         for (p1=&line[strlen(line)-1]; isspace(*p1); --p1)
  972.             *p1 = '\0';
  973.         if (strchr(p, ':') != NULL) {
  974.             strcpy(stanza, p);
  975.             if (stanza[strlen(stanza)-1] == ':')
  976.                 stanza[strlen(stanza)-1] = '\0';
  977.             continue;
  978.         }
  979.         if (my_strstr(p, "device") != NULL) {
  980.             if (stanza[0] != '\0') {
  981.                 if (num_printers >= MAX_NUM_PRINTERS) {
  982.                     fprintf(stdout, "bwnfsd: [get_printers] Max number of printers (%d) exceeded.\nRecompile with larger value\n", MAX_NUM_PRINTERS);
  983.                     fflush(stdout);
  984.                     goto outoutout;
  985.                 }
  986.                 if (strlen(stanza) <= 11) {
  987.                     printers[num_printers].queuename = my_strdup(stanza);
  988.                     printers[num_printers].queuecomment = NULL;
  989.                     printers[num_printers].queuestatus = WNPRQ_ACTIVE;
  990.                     printers[num_printers].numphysicalprinters = 0;
  991.                     printers[num_printers].lasttime = 0L;
  992.                     printers[num_printers].head = NULL;
  993.                     num_printers++;
  994.                 } else
  995.                     fprintf(stdout, "bwnfsd: [get_printer_list] Printer name \"%s\" exceeds 11 characters; not available for linking\n", stanza);
  996.                 stanza[0] = '\0';
  997.             }
  998.         }
  999.     }
  1000. outoutout:
  1001.     fclose(f);
  1002. #else
  1003. #ifdef FIND_QUEUES_PRINTCAP
  1004.     if ((f=fopen("/etc/printcap","r")) == NULL) {
  1005.         fprintf(stdout, "bwnfsd: File /etc/printcap was not found.\n");
  1006.         fprintf(stdout, "        No printers are available for use.\n");
  1007.         fflush(stdout);
  1008.         return;
  1009.     }
  1010.  
  1011.     while (fgets(line,sizeof(line)-1,f) != NULL) {
  1012.         start=num_printers;
  1013. multi_line:
  1014.         if ((p=strchr(line,'#')) != NULL)
  1015.             *p = '\0';
  1016.         if ((p=strchr(line,':')) != NULL)
  1017.             *p = '\0';
  1018.         if ((end=line+strlen(line)) == line)
  1019.             continue;
  1020.         if (*(end-1) == '\n')
  1021.             *(--end) = '\0';
  1022.         if (*(end-1) == '\\') {
  1023.             *(--end) = '\0';
  1024.             if ((sizeof(line)-(end-line)) <= 0) {
  1025.                 fprintf(stdout, "bwnfsd: [get_printers] Multi-line line too long in /etc/printcap.\n");
  1026.                 fflush(stdout);
  1027.                 break;
  1028.             }
  1029.             if (fgets(end,sizeof(line)-(end-line),f) != NULL)
  1030.                 goto multi_line;
  1031.         }
  1032.         for (p=line; p<=end; ) {
  1033.             while ((*p == ' ') || (*p == '\t'))
  1034.                 p++;
  1035.             if (!*p)
  1036.                 break;
  1037.             p1 = p;
  1038.             while (strchr(" \t|",*p1) == NULL)
  1039.                 p1++;
  1040.             if ((*p1 == ' ') || (*p1 == '\t')) {
  1041.                 while (strchr("|",*p1) == NULL)
  1042.                     p1++;
  1043.                 *p1 = '\0';
  1044.                 while ((p[strlen(p)-1] == ' ') || (p[strlen(p)-1] == '\t'))
  1045.                     p[strlen(p)-1] = '\0';
  1046.                 if ((strchr(p,' ') != NULL) || (strchr(p,'\t') != NULL)) {
  1047.                     for (i=start; i<num_printers; i++)
  1048.                         printers[i].queuecomment = my_strdup(p);
  1049.                     start = num_printers;
  1050.                     p = p1 + 1;
  1051.                     continue;
  1052.                 }
  1053.             } else
  1054.                 *p1 = '\0';
  1055.             if (*p) {
  1056.                 if (num_printers >= MAX_NUM_PRINTERS) {
  1057.                     fprintf(stdout, "bwnfsd: [get_printers] Max number of printers (%d) exceeded.\nRecompile with larger value\n", MAX_NUM_PRINTERS);
  1058.                     fflush(stdout);
  1059.                     goto outoutout;
  1060.                 }
  1061.                 if (strlen(p) <= 11) {
  1062.                     printers[num_printers].queuename = my_strdup(p);
  1063.                     printers[num_printers].queuecomment = NULL;
  1064.                     printers[num_printers].queuestatus = WNPRQ_ACTIVE;
  1065.                     printers[num_printers].numphysicalprinters = 0;
  1066.                     printers[num_printers].lasttime = 0L;
  1067.                     printers[num_printers].head = NULL;
  1068.                     num_printers++;
  1069.                 } else
  1070.                     fprintf(stdout, "bwnfsd: [get_printer_list] Printer name \"%s\" exceeds 11 characters; not available for linking\n", p);
  1071.             }
  1072.             p = p1 + 1;
  1073.         }
  1074.     }
  1075. outoutout:
  1076.     fclose(f);
  1077. #else
  1078.  error FIND_QUEUES_Something must be specified
  1079. #endif
  1080. #endif
  1081. #endif
  1082.     if (debugmode) {
  1083.           fprintf(stdout, "bwnfsd: [get_printers] Following devices are available:\n");
  1084.           for (i=0; i<num_printers; i++)
  1085.               fprintf(stdout, "bwnfsd:                 %s\n", printers[i].queuename);
  1086.     }
  1087.  
  1088. }
  1089.  
  1090. static struct var_file {
  1091.     int     status;
  1092.     int     dir_size;
  1093.     char    *dir_handle;
  1094. } f;
  1095.  
  1096. /*
  1097.  *       DOS 3.1 Sharing and Unsharing code. Uses the same format for rpc.lockd
  1098.  *       as BWNFSD, so some parameters are ignored. The cookie under rpc.lockd
  1099.  *       must be 4 bytes long under BWNFSD.
  1100.  */
  1101. xdr_share(xdrsp, l)
  1102.     XDR *xdrsp;
  1103.     struct locking *l;
  1104. {
  1105. int  i;
  1106. char g[32];
  1107. char *p;
  1108.  
  1109.     if (debugmode > 1) {
  1110.         fprintf(stdout, "bwnfsd: [xdr_share] called for %s, ofs = %ld, len = %ld\n", l->name, l->offset, l->length);
  1111.         fprintf(stdout, "bwnfsd:             mode = %u, access = %u, stat = %u, sequence = %u\n", l->mode, l->access, l->stat, l->sequence);
  1112.     }
  1113.     if (!xdr_int(xdrsp, &l->cookie))
  1114.         return(0);
  1115.     if (l->cookie != 4)
  1116.         return(0);
  1117.     if (!xdr_int(xdrsp, &l->cookie))
  1118.         return(0);
  1119.  
  1120.     p = l->name;
  1121.     if (strlen(p) > 17) {
  1122.         *(p+17) = '\0';
  1123.         if (debugmode)
  1124.             fprintf(stdout, "bwnfsd: [xdr_share] name truncated to %s\n", p);
  1125.     }
  1126.     if (!xdr_string(xdrsp, &p, 17))
  1127.         return(0);
  1128.     p = l->fh;
  1129.     if (!xdr_bytes(xdrsp, &p, &i, 32))
  1130.         return(0);
  1131.     p = g;
  1132.     if (!xdr_bytes(xdrsp,&p,&i,32))
  1133.         return(0);
  1134.     if (!xdr_int(xdrsp, &l->mode))
  1135.         return(0);
  1136.     if (!xdr_int(xdrsp, &l->access))
  1137.         return(0);
  1138.  
  1139.     if (debugmode)
  1140.         fprintf(stdout, "bwnfsd: [xdr_share] returns (1)\n");
  1141.     return(1);
  1142. }
  1143.  
  1144.  
  1145. /*
  1146.  *       Get Printers response
  1147.  */
  1148. int
  1149. xdr_printers(xdrsp,l)
  1150.     XDR *xdrsp;
  1151.     char *l;
  1152. {
  1153. int i;
  1154. char *p;
  1155.  
  1156.     if (debugmode)
  1157.         fprintf(stdout, "bwnfsd: [xdr_printers] called\n");
  1158.     i = num_printers;
  1159.     if (!xdr_int(xdrsp, &i))
  1160.         return(0);
  1161.     for (i=0; i<num_printers; i++) {
  1162.         p = printers[i].queuename;
  1163.         if (strlen(p) > 24) {
  1164.             *(p+24) = '\0';
  1165.             if (debugmode)
  1166.                 fprintf(stdout, "bwnfsd: [xdr_printers] queuename truncated to %s\n", p);
  1167.         }
  1168.         if (!xdr_string(xdrsp, &p, 24))
  1169.             return(0);
  1170.         p = printers[i].queuecomment;
  1171.         if (p == NULL)
  1172.             p = "";
  1173.         if (strlen(p) > 255) {
  1174.             *(p+255) = '\0';
  1175.             if (debugmode)
  1176.                 fprintf(stdout, "bwnfsd: [xdr_printers] queuecomment truncated to %s\n", p);
  1177.         }
  1178.         if (!xdr_string(xdrsp, &p, 255))
  1179.             return(0);
  1180.     }
  1181.  
  1182.     if (debugmode)
  1183.         fprintf(stdout, "bwnfsd: [xdr_printers] returns (1)\n");
  1184.     return(1);
  1185. }
  1186.  
  1187. /*
  1188.  *       DOS 3.1 Share response.
  1189.  */
  1190. int
  1191. xdr_shareres(xdrsp,l)
  1192.     XDR *xdrsp;
  1193.     struct locking *l;
  1194. {
  1195. int i;
  1196. char *p;
  1197.  
  1198.     if (debugmode)
  1199.         fprintf(stdout, "bwnfsd: [xdr_shareres] called by %s\n", l->name);
  1200.     i = 4;
  1201.     if (!xdr_int(xdrsp, &i))
  1202.         return(0);
  1203.     if (!xdr_int(xdrsp, &l->cookie))
  1204.         return(0);
  1205.     if (!xdr_int(xdrsp,&l->stat))
  1206.         return(0);
  1207.     l->sequence++;
  1208.     if (!xdr_int(xdrsp,&l->sequence))
  1209.         return(0);
  1210.  
  1211.     if (debugmode)
  1212.         fprintf(stdout, "bwnfsd: [xdr_shareres] returns (1)\n");
  1213.     return(1);
  1214. }
  1215.  
  1216.  
  1217. /*
  1218.  *       DOS 3.1 locking request. Note that several parameters are ignored.
  1219.  */
  1220. int
  1221. xdr_lock(xdrsp,l)
  1222.     XDR *xdrsp;
  1223.     struct locking *l;
  1224. {
  1225. int  i;
  1226. union {
  1227.    char g[32];
  1228.    unsigned long lockowner;
  1229. } g;
  1230. char *p;
  1231.  
  1232.     if (debugmode) {
  1233.         fprintf(stdout, "bwnfsd: [xdr_lock] called by %s\n", l->name);
  1234.         if (debugmode > 1)
  1235.             fprintf(stdout, "bwnfsd:            ofs = %lu, len = %lu\n", l->offset, l->length);
  1236.     }
  1237.     if (!xdr_int(xdrsp, &l->cookie))
  1238.         return(0);
  1239.     if (!xdr_int(xdrsp, &l->cookie))
  1240.         return(0);
  1241.     if (!xdr_int(xdrsp, &i))
  1242.         return(0);
  1243.     if (!xdr_int(xdrsp, &i))
  1244.         return(0);
  1245.     p = l->name;
  1246.     if (strlen(p) > 17) {
  1247.         *(p+17) = '\0';
  1248.         if (debugmode)
  1249.             fprintf(stdout, "bwnfsd: [xdr_lock] name truncated to %s\n", p);
  1250.     }
  1251.     if (!xdr_string(xdrsp, &p, 17))
  1252.         return(0);
  1253.     p = l->fh;
  1254.     if (!xdr_bytes(xdrsp,&p,&i,32))
  1255.         return(0);
  1256.     p = (char *)&g;
  1257.     if (!xdr_bytes(xdrsp,&p,&i,32))
  1258.         return(0);
  1259.     l->lockowner = g.lockowner;
  1260.     if (!xdr_int(xdrsp,&i))
  1261.         return(0);
  1262.     if (!xdr_int(xdrsp, &l->offset))
  1263.         return(0);
  1264.     if (!xdr_int(xdrsp, &l->length))
  1265.         return(0);
  1266.     if (debugmode > 1)
  1267.         fprintf(stdout, "bwnfsd: [xdr_lock] returns (1)\n");
  1268.     return(1);
  1269. }
  1270.  
  1271.  
  1272. /*
  1273.  *       DOS 3.1 unlock request. Note that several parameters are ignored.
  1274.  */
  1275. xdr_unlock(xdrsp,l)
  1276.     XDR *xdrsp;
  1277.     struct locking *l;
  1278. {
  1279. int  i;
  1280. char g[32];
  1281. char *p;
  1282.  
  1283.     if (debugmode) {
  1284.         fprintf(stdout, "bwnfsd: [xdr_unlock] called by %s\n", l->name);
  1285.         if (debugmode > 1)
  1286.             fprintf(stdout, "bwnfsd:              ofs = %lu, len = %lu\n", l->offset, l->length);
  1287.     }
  1288.     if (!xdr_int(xdrsp, &l->cookie))
  1289.         return(0);
  1290.     if (!xdr_int(xdrsp, &l->cookie))
  1291.         return(0);
  1292.  
  1293.     p = l->name;
  1294.     if (strlen(p) > 17) {
  1295.         *(p+17) = '\0';
  1296.         if (debugmode)
  1297.             fprintf(stdout, "bwnfsd: [xdr_unlock] name truncated to %s\n", p);
  1298.     }
  1299.     if (!xdr_string(xdrsp, &p, 17))
  1300.         return(0);
  1301.     p = l->fh;
  1302.     if (!xdr_bytes(xdrsp, &p, &i, 32))
  1303.         return(0);
  1304.     p = g;
  1305.     if (!xdr_bytes(xdrsp, &p, &i, 32))
  1306.         return(0);
  1307.     if (!xdr_int(xdrsp,&i))
  1308.         return(0);
  1309.     if (!xdr_int(xdrsp, &l->offset))
  1310.         return(0);
  1311.     if (!xdr_int(xdrsp, &l->length))
  1312.         return(0);
  1313.     if (debugmode > 1)
  1314.         fprintf(stdout, "bwnfsd: [xdr_unlock] returns (1)\n");
  1315.     return(1);
  1316. }
  1317.  
  1318. /*
  1319.  *       Send Locking response.
  1320.  */
  1321. int
  1322. xdr_res(xdrsp,l)
  1323.     XDR *xdrsp;
  1324.     struct locking *l;
  1325. {
  1326. int i;
  1327. char *p;
  1328.  
  1329.     if (debugmode > 1)
  1330.         fprintf(stdout, "bwnfsd: [xdr_res] called\n");
  1331.     i = 4;
  1332.     if (!xdr_int(xdrsp, &i))
  1333.         return(0);
  1334.     if (!xdr_int(xdrsp, &l->cookie))
  1335.         return(0);
  1336.     if (!xdr_int(xdrsp,&l->stat))
  1337.         return(0);
  1338.     if (debugmode)
  1339.         fprintf(stdout, "bwnfsd: [xdr_res] returns (1)\n");
  1340.     return(1);
  1341. }
  1342.  
  1343.  
  1344. /*
  1345.  *       Remove all DOS 3.1 locks and shares, note that the PC's name is
  1346.  *       a maximum of 16 chaarcters.
  1347.  */
  1348. int
  1349. xdr_get_lock_name(xdrsp, l)
  1350.     XDR *xdrsp;
  1351.     char *l;
  1352. {
  1353.     if (debugmode)
  1354.         fprintf(stdout, "bwnfsd: [xdr_get_lock_name] called\n");
  1355.     if (strlen(l) > 17) {
  1356.         *(l+17) = '\0';
  1357.         if (debugmode)
  1358.             fprintf(stdout, "bwnfsd: [xdr_get_lock_name] name truncated to %s\n", l);
  1359.     }
  1360.     return(xdr_string(xdrsp, &l, 17));
  1361. }
  1362.  
  1363. /*
  1364.  *       Send a redirect to a new IP during an authorization request.
  1365.  */
  1366. int
  1367. xdr_new_ip(xdrsp, ip)
  1368.     XDR *xdrsp;
  1369.     unsigned long *ip;
  1370. {
  1371. int i;
  1372.  
  1373.     if (debugmode)
  1374.         fprintf(stdout, "bwnfsd: [xdr_new_ip] called\n");
  1375.     i = 3;
  1376.     if (!xdr_int(xdrsp, &i))
  1377.         return(0);
  1378.     if (!xdr_int(xdrsp, ip))
  1379.         return(0);
  1380.     if (debugmode)
  1381.         fprintf(stdout, "bwnfsd: [xdr_new_ip] returns (1)\n");
  1382.     return(1);
  1383. }
  1384.  
  1385. /*
  1386.  *       Get GROUP name.
  1387.  */
  1388. int
  1389. xdr_g_string(xdrsp, st)
  1390.     XDR *xdrsp;
  1391.     char *st;
  1392. {
  1393. char *p;
  1394.  
  1395.     if (debugmode)
  1396.         fprintf(stdout, "bwnfsd: [xdr_g_string] called\n");
  1397.     p = st;
  1398.     if (strlen(p) > 32) {
  1399.         *(p+32) = '\0';
  1400.         if (debugmode)
  1401.             fprintf(stdout, "bwnfsd: [xdr_g_string] string truncated to %s\n", p);
  1402.     }
  1403.     if (!xdr_string(xdrsp, &p, 32))
  1404.         return(0);
  1405.     if (debugmode)
  1406.         fprintf(stdout, "bwnfsd: [xdr_g_string] returns (1)\n");
  1407.     return(1);
  1408. }
  1409.  
  1410. /*
  1411.  *       Send Status and GID
  1412.  */
  1413. int
  1414. xdr_send_gid(xdrsp, st)
  1415.     XDR *xdrsp;
  1416.     char *st;
  1417. {
  1418. int   *i, j;
  1419.  
  1420.     if (debugmode)
  1421.         fprintf(stdout, "bwnfsd: [xdr_send_gid] called with st = %s\n", st);
  1422.     i = get_gr_gid(st);
  1423.     if (i == NULL) {
  1424.         j = 2;
  1425.         if (!xdr_int(xdrsp,&j))
  1426.             return(0);
  1427.     } else {
  1428.         j = 0;
  1429.         if (!xdr_int(xdrsp,&j))
  1430.             return(0);
  1431.         if (!xdr_int(xdrsp,i))
  1432.             return(0);
  1433.     }
  1434.     if (debugmode)
  1435.         fprintf(stdout, "bwnfsd: [xdr_send_gid] returns (1)\n");
  1436.     return(1);
  1437. }
  1438.  
  1439. /*
  1440.  *       Get list of UIDs to translate to text.
  1441.  */
  1442. int
  1443. xdr_nuids(xdrsp, luids)
  1444.     XDR *xdrsp;
  1445.     int luids[NUSRS+1];
  1446. {
  1447. int i;
  1448.  
  1449.     if (debugmode)
  1450.         fprintf(stdout, "bwnfsd: [xdr_nuids] called\n");
  1451.     if (!xdr_int(xdrsp,&luids[0]))
  1452.         return(0);
  1453.     if ((luids[0] < 0) || (luids[0] > 16))
  1454.         luids[0] = 0;
  1455.     for (i=1; i<=luids[0]; i++)
  1456.        if (!xdr_int(xdrsp,&luids[i]))
  1457.         return(0);
  1458.     if (debugmode)
  1459.         fprintf(stdout, "bwnfsd: [xdr_nuids] returns (1)\n");
  1460.     return(1);
  1461. }
  1462.  
  1463.  
  1464. /*
  1465.  *       Get list of GIDs to translate to text.
  1466.  */
  1467. int
  1468. xdr_ngids(xdrsp, lgids)
  1469.     XDR *xdrsp;
  1470.     int lgids[NGRPS+1];
  1471. {
  1472. int i;
  1473.  
  1474.     if (debugmode)
  1475.         fprintf(stdout, "bwnfsd: [xdr_ngids] called\n");
  1476.  
  1477.     if (!xdr_int(xdrsp,&lgids[0]))
  1478.         return(0);
  1479.     if ((lgids[0] < 0) || (lgids[0] > 16))
  1480.         lgids[0] = 0;
  1481.     for (i=1; i<=lgids[0]; i++)
  1482.         if (!xdr_int(xdrsp,&lgids[i]))
  1483.             return(0);
  1484.     if (debugmode)
  1485.         fprintf(stdout, "bwnfsd: [xdr_ngids] returns (1)\n");
  1486.     return(1);
  1487. }
  1488.  
  1489.  
  1490. /*
  1491.  *       Send Usernames translated from UIDS.
  1492.  */
  1493. xdr_send_usernames(xdrsp, luids)
  1494.     XDR *xdrsp;
  1495.     int luids[NUSRS+1];
  1496. {
  1497. int i, j;
  1498. char *p;
  1499.  
  1500.     if (debugmode)
  1501.         fprintf(stdout, "bwnfsd: [xdr_send_usernames] called\n");
  1502.     for (i=1; i<=luids[0]; i++) {
  1503.         p = get_ui_name(luids[i]);
  1504.         if (debugmode)
  1505.             fprintf(stdout, "bwnfsd: [xdr_send_usernames] p = %s\n", p);
  1506.         if (p == NULL) {
  1507.             j = 0;
  1508.             if (!xdr_int(xdrsp, &j))
  1509.                 return(0);
  1510.         } else {
  1511.             if (strlen(p) > 32) {
  1512.                 *(p+32) = '\0';
  1513.                 if (debugmode)
  1514.                     fprintf(stdout, "bwnfsd: [xdr_send_usernames] name truncated to %s\n", p);
  1515.             }
  1516.             if (!xdr_string(xdrsp, &p, 32))
  1517.                 return(0);
  1518.         }
  1519.     }
  1520.     if (debugmode)
  1521.         fprintf(stdout, "bwnfsd: [xdr_send_usernames] returns (1)\n");
  1522.     return(1);
  1523. }
  1524.  
  1525. /*
  1526.  *       Send Group names translated from GIDS.
  1527.  */
  1528. int
  1529. xdr_send_names(xdrsp, lgids)
  1530.     XDR *xdrsp;
  1531.     int lgids[NGRPS+1];
  1532. {
  1533. int i, j;
  1534. char *p;
  1535.  
  1536.     if (debugmode)
  1537.         fprintf(stdout, "bwnfsd: [xdr_send_names] called\n");
  1538.     for (i=1; i<=lgids[0]; i++) {
  1539.         p = get_gr_name(lgids[i]);
  1540.         if (debugmode)
  1541.             fprintf(stdout, "bwnfsd: [xdr_send_names] p = %s\n", p);
  1542.         if (p == NULL) {
  1543.             j = 0;
  1544.             if (!xdr_int(xdrsp, &j))
  1545.                 return(0);
  1546.         } else {
  1547.             if (strlen(p) > 32) {
  1548.                 *(p+32) = '\0';
  1549.                 if (debugmode)
  1550.                     fprintf(stdout, "bwnfsd: [xdr_send_names] name truncated to %s\n", p);
  1551.             }
  1552.             if (!xdr_string(xdrsp, &p, 32))
  1553.                 return(0);
  1554.         }
  1555.     }
  1556.     if (debugmode)
  1557.         fprintf(stdout, "bwnfsd: [xdr_send_names] returns (1)\n");
  1558.     return(1);
  1559. }
  1560.  
  1561.  
  1562. /*
  1563.  *       Return fhandle of spool directory. Note a loop of XDR_INTS is
  1564.  *       used to allow this to compile on all systems.
  1565.  */
  1566. xdr_file(xdrsp, file_var)
  1567.     XDR *xdrsp;
  1568.     struct var_file *file_var;
  1569. {
  1570. int i;
  1571.  
  1572.     if (debugmode)
  1573.         fprintf(stdout, "bwnfsd: [xdr_file] called\n");
  1574.     if (!xdr_int(xdrsp,&file_var->status))
  1575.         return(0);
  1576.     if (file_var->status != 0) {
  1577.         if (debugmode > 1)
  1578.             fprintf(stdout, "bwnfsd: [xdr_file] status = %u, returns (1)\n", file_var->status);
  1579.         return(1);
  1580.     }
  1581.     for (i=0; i<32; i+=4)
  1582.         if (!xdr_int(xdrsp, (&file_var->dir_handle[0]) + i))
  1583.             return(0);
  1584.     if (debugmode)
  1585.         fprintf(stdout, "bwnfsd: [xdr_file] returns (1)\n");
  1586.     return(1);
  1587. }
  1588.  
  1589.  
  1590. /*
  1591.  *      Spool a file to the printer:
  1592.  *
  1593.  *              Parameters:
  1594.  *                      printer_name (fixed 11 bytes)
  1595.  *                      file_name    (fixed 8 bytes) (Internet Address in Hex).
  1596.  *                      extension     xdr_int (filename is form C02A0405.xxx)
  1597.  */
  1598. int
  1599. xdr_print(xdrsp)
  1600.     XDR *xdrsp;
  1601. {
  1602. struct stat buf;
  1603. struct passwd *pw1;
  1604. char *p;
  1605. int i;
  1606.  
  1607.     if (debugmode)
  1608.         fprintf(stdout, "bwnfsd: [xdr_print] called\n");
  1609.     i = 11;
  1610.     p = printer;
  1611.     if (!xdr_bytes(xdrsp,&p,&i, 11)) {
  1612.         if (debugmode > 1)
  1613.             fprintf(stdout, "bwnfsd: [xdr_print] printer = %s, file = %s, ext = %s\n", printer, file_name, extension);
  1614.         return(0);
  1615.     }
  1616.     printer[11] = ' ';
  1617.     *strchr(printer, ' ') = '\0';
  1618.     i = 8;
  1619.     p = file_name;
  1620.     if (!xdr_bytes(xdrsp,&p,&i, 8)) {
  1621.         if (debugmode > 1)
  1622.             fprintf(stdout, "bwnfsd: [xdr_print] printer = %s, file = %s, ext = %s\n", printer, file_name, extension);
  1623.         return(0);
  1624.     }
  1625.     file_name[8] = '\0';
  1626.     if (!xdr_int(xdrsp,&extension)) {
  1627.         if (debugmode > 1)
  1628.             fprintf(stdout, "bwnfsd: [xdr_print] printer = %s, file = %s, ext = %s\n", printer, file_name, extension);
  1629.         return(0);
  1630.     }
  1631.     strlwr(file_name);
  1632.     sprintf(file,"%s/%s.%03d",spool_dir,file_name,extension);
  1633. #ifdef FOURTEEN_CHAR
  1634.     sprintf(file1,"%s/%s.%03dq",spool_dir,file_name,extension);
  1635. #else
  1636.     sprintf(file1,"%s/%s.%03dqueued",spool_dir,file_name,extension);
  1637. #endif
  1638.     if (debugmode > 1)
  1639.         fprintf(stdout, "bwnfsd: [xdr_print] f = %s, f1 = %s\n", file, file1);
  1640.     jobname  = NULL;
  1641.     do_print = -1;
  1642.     if (stat(file, &buf) == 0) {
  1643.         do_print = rename(file, file1);
  1644.         if (debugmode && do_print)
  1645.             fprintf(stdout, "bwnfsd: [xdr_print] rename failed, error = %d\n", errno);
  1646.         pw1 = getpwuid((int) buf.st_uid);
  1647.         if (pw1 != NULL) {
  1648.             if (debugmode)
  1649.                 fprintf(stdout, "bwnfsd: [xdr_print] jobname = %s\n", pw1->pw_name);
  1650.             jobname = pw1->pw_name;
  1651.         }
  1652.     } else
  1653.         if (debugmode)
  1654.             if (errno == ENOENT)
  1655.                 fprintf(stdout, "bwnfsd: [xdr_print] duplicate close request\n");
  1656.             else
  1657.                 fprintf(stdout, "bwnfsd: [xdr_print] stat failed, errno = %d\n",errno);
  1658.     if (debugmode)
  1659.         fprintf(stdout, "bwnfsd: [xdr_print] returns (1)\n");
  1660.     return(1);
  1661. }
  1662.  
  1663. struct auth_struct {
  1664.     unsigned long ip;
  1665.     int type;
  1666.     char device[13];
  1667.     char login_text[64];
  1668.     char *username;
  1669.     char *password;
  1670. } auth_request;
  1671.  
  1672. /*
  1673.  *       Request Authorization:
  1674.  *               Parameters:
  1675.  *                       IP_Address of server host (XDR_INT)
  1676.  *                       Type of request (XDR_INT) (4 - disk, 3 - printer)
  1677.  *                       Device to link  (XDR_BYTES max 12) (printer name)
  1678.  *                       Username/Password (XDR_BYTES max 64)
  1679.  */
  1680. int
  1681. xdr_auth_request(xdrsp, auth)
  1682.     XDR *xdrsp;
  1683.     struct auth_struct *auth;
  1684. {
  1685. int   i, j, x, y;
  1686. char  *p;
  1687.  
  1688.     if (!xdr_int(xdrsp,&auth->ip))
  1689.         return(0);
  1690.     if (!xdr_int(xdrsp,&auth->type))
  1691.         return(0);
  1692.     i = 11;
  1693.     p = auth->device;
  1694.     if (!xdr_bytes(xdrsp,&p,&i, 12))
  1695.         return(0);
  1696.     auth->device[11] = ' ';
  1697.     p=strchr(auth->device, ' ');
  1698.     if (p == NULL)
  1699.         return(0);
  1700.     *p = '\0';
  1701.     i = 64;
  1702.     p = auth->login_text;
  1703.     if (!xdr_bytes(xdrsp,&p,&i,64))
  1704.         return(0);
  1705.     if (i < 6)
  1706.         auth->type = -1;
  1707.     p = auth->login_text;
  1708.     for (x= -1,j=0; j<i; j++) {
  1709.         y = *p;
  1710.         x ^= *p;
  1711.         *p++ = x;
  1712.         x = y;
  1713.     }
  1714.     auth->username = auth->login_text + 2;
  1715.     auth->password = auth->username + strlen(auth->username) + 1;
  1716.     if (debugmode) {
  1717.         fprintf(stdout, "bwnfsd: [xdr_auth_request] called\n");
  1718.         fprintf(stdout, "bwnfsd:   Link to %d.%d.%d.%d\n",
  1719.                (auth->ip >> 24) & 0xff, (auth->ip >> 16) & 0xff,
  1720.                (auth->ip >>  8) & 0xff, (auth->ip)       & 0xff);
  1721.         fprintf(stdout, "bwnfsd:   Request type     : %u (%s)\n", auth->type, auth->type==3?"print request":"disk request");
  1722.         fprintf(stdout, "bwnfsd:   Requested Device : %s\n", auth->device);
  1723.         fprintf(stdout, "bwnfsd:   Username         : %s\n", auth->username);
  1724. /*
  1725.  *              fprintf(stdout, "bwnfsd:   Password         : %s\n", auth->password);
  1726.  */
  1727.         fprintf(stdout, "bwnfsd: [xdr_auth_request] returns (1)\n");
  1728.     }
  1729.     return(1);
  1730. }
  1731.  
  1732. struct name_struct {
  1733.     char usr_login[64];
  1734.     char *usr_name;
  1735. } name_request;
  1736.  
  1737. int
  1738. xdr_name_request(xdrsp, name)
  1739.     XDR *xdrsp;
  1740.     struct name_struct *name;
  1741. {
  1742. char *p;
  1743.  
  1744.     p = name->usr_login;
  1745.     name->usr_name = name->usr_login;
  1746.     if (strlen(p) > 32) {
  1747.         *(p+32) = '\0';
  1748.         if (debugmode)
  1749.             fprintf(stdout, "bwnfsd: [xdr_name_request] name truncated to %s\n", p);
  1750.     }
  1751.     if (!xdr_string(xdrsp, &p, 32))
  1752.         return(0);
  1753.     if (debugmode)
  1754.         fprintf(stdout, "bwnfsd: [xdr_name_request] called\n");
  1755.     return(1);
  1756. }
  1757.  
  1758. /*
  1759.  *       Send successful authorization reply.
  1760.  *               Results:
  1761.  *                 UID (XDR_INT)
  1762.  *                 GID (XDR_INT)
  1763.  *                 GID count (XDR_INT)
  1764.  *                 GIDs (XDR_INT)        (GID count entries)
  1765.  */
  1766. int
  1767. xdr_pw(xdrsp,pwd)
  1768.     XDR   *xdrsp;
  1769.     struct passwd *pwd;
  1770. {
  1771. int   i;
  1772. struct mm_gidss *gg;
  1773.  
  1774.     if (debugmode)
  1775.         fprintf(stdout, "bwnfsd: [xdr_pw] called\n");
  1776.     i  = 0;
  1777.     gg = get_gids(pwd->pw_uid,pwd->pw_gid,pwd->pw_name);
  1778.     if (debugmode > 1)
  1779.         fprintf(stdout, "bwnfsd: uid = %u, gid = %u, gids = %u\n", gg->mm_uid, gg->mm_gid, gg->mm_gids[0]);
  1780.     if (!xdr_int(xdrsp,&i))
  1781.         return(0);
  1782.     i = pwd->pw_uid;
  1783.     if (!xdr_int(xdrsp,&i))
  1784.         return(0);
  1785.     i = pwd->pw_gid;
  1786.     if (!xdr_int(xdrsp,&i))
  1787.         return(0);
  1788.     if (!xdr_int(xdrsp,&gg->mm_gid_count))
  1789.         return(0);
  1790.     for (i=0; i<gg->mm_gid_count; i++)
  1791.         if (!xdr_int(xdrsp,&gg->mm_gids[i]))
  1792.             return(0);
  1793.  
  1794.     if (debugmode > 1)
  1795.         fprintf(stdout, "bwnfsd: [xdr_pw] returns (1)\n");
  1796.     return(1);
  1797. }
  1798.  
  1799. int
  1800. xdr_get_printq(xdrsp,pq)
  1801.     XDR *xdrsp;
  1802.     struct printqs *pq;
  1803. {
  1804. char *p;
  1805.  
  1806.     if (debugmode)
  1807.         fprintf(stdout, "bwnfsd: [xdr_get_printq] called\n");
  1808.     p = pq->queuename;
  1809.     if (strlen(p) > 32) {
  1810.         *(p+32) = '\0';
  1811.         if (debugmode)
  1812.             fprintf(stdout, "bwnfsd: [xdr_get_printq] queuename truncated to %s\n", p);
  1813.     }
  1814.     if (!xdr_string(xdrsp, &p, 32))
  1815.         return(0);
  1816.     p = pq->username;
  1817.     if (strlen(p) > 32) {
  1818.         *(p+32) = '\0';
  1819.         if (debugmode)
  1820.             fprintf(stdout, "bwnfsd: [xdr_get_printq] username truncated to %s\n", p);
  1821.     }
  1822.     if (!xdr_string(xdrsp, &p, 32))
  1823.         return(0);
  1824.     return(1);
  1825. }
  1826.  
  1827. int
  1828. xdr_cancel_job(xdrsp,pq)
  1829.     XDR *xdrsp;
  1830.     struct printqs *pq;
  1831. {
  1832. char *p;
  1833.  
  1834.     if (debugmode)
  1835.         fprintf(stdout, "bwnfsd: [xdr_cancel_job] called\n");
  1836.     p = pq->queuename;
  1837.     if (strlen(p) > 32) {
  1838.         *(p+32) = '\0';
  1839.         if (debugmode)
  1840.             fprintf(stdout, "bwnfsd: [xdr_cancel_job] queuename truncated to %s\n", p);
  1841.     }
  1842.     if (!xdr_string(xdrsp, &p, 32))
  1843.         return(0);
  1844.     p = pq->username;
  1845.     if (strlen(p) > 32) {
  1846.         *(p+32) = '\0';
  1847.         if (debugmode)
  1848.             fprintf(stdout, "bwnfsd: [xdr_cancel_job] username truncated to %s\n", p);
  1849.     }
  1850.     if (!xdr_string(xdrsp, &p, 32))
  1851.         return(0);
  1852.     if (!xdr_int(xdrsp,&pq->printer_number))
  1853.         return(0);
  1854.     return(1);
  1855. }
  1856.  
  1857. int
  1858. xdr_send_printq(xdrsp,pq)
  1859.     XDR *xdrsp;
  1860.     struct printqs *pq;
  1861. {
  1862. int i, pn;
  1863. struct queueentry *qe;
  1864. char *pp;
  1865.  
  1866.     if (debugmode)
  1867.         fprintf(stdout, "bwnfsd: [xdr_send_printq] called\n");
  1868.     pn = pq->printer_number;
  1869.     i = pn == -1;
  1870.     if (!xdr_int(xdrsp,&i))
  1871.         return(0);
  1872.     if (i != 0)
  1873.         return(1);
  1874.     pp = printers[pn].queuecomment;
  1875.     if (pp == NULL)
  1876.         pp = "";
  1877.     if (strlen(pp) > 32) {
  1878.         *(pp+32) = '\0';
  1879.         if (debugmode)
  1880.             fprintf(stdout, "bwnfsd: [xdr_send_printq] queuecomment truncated to %s\n", pp);
  1881.     }
  1882.     if (!xdr_string(xdrsp, &pp, 32))
  1883.         return(0);
  1884.     if (!xdr_int(xdrsp,&printers[pn].queuestatus))
  1885.         return(0);
  1886.     if (!xdr_int(xdrsp,&printers[pn].numphysicalprinters))
  1887.         return(0);
  1888.     qe = printers[pn].head;
  1889.     i = 1;
  1890.     while (qe) {
  1891.         if ((*pq->username != '\0') && (strcmp(pq->username, qe->username) != 0)) {
  1892.             qe = qe->next;
  1893.             continue;
  1894.         }
  1895.         if (!xdr_int(xdrsp,&i))
  1896.             return(0);
  1897.         if (!xdr_int(xdrsp,&qe->jobid))
  1898.             return(0);
  1899.         pp = qe->username;
  1900.         if (pp == NULL)
  1901.             pp = "";
  1902.         if (strlen(pp) > 32) {
  1903.             *(pp+32) = '\0';
  1904.             if (debugmode)
  1905.                 fprintf(stdout, "bwnfsd: [xdr_send_printq] username truncated to %s\n", pp);
  1906.         }
  1907.         if (!xdr_string(xdrsp, &pp, 32))
  1908.             return(0);
  1909.         pp = qe->params;
  1910.         if (pp == NULL)
  1911.             pp = "";
  1912.         if (strlen(pp) > 255) {
  1913.             *(pp+255) = '\0';
  1914.             if (debugmode)
  1915.                 fprintf(stdout, "bwnfsd: [xdr_send_printq] params truncated to %s\n", pp);
  1916.         }
  1917.         if (!xdr_string(xdrsp, &pp, 255))
  1918.             return(0);
  1919.         if (!xdr_int(xdrsp,&qe->queueposition))
  1920.             return(0);
  1921.         if (!xdr_int(xdrsp,&qe->jobstatus))
  1922.             return(0);
  1923.         if (!xdr_long(xdrsp,&qe->timesubmitted))
  1924.             return(0);
  1925.         if (!xdr_long(xdrsp,&qe->size))
  1926.             return(0);
  1927.         if (!xdr_int(xdrsp,&qe->copies))
  1928.             return(0);
  1929.         pp = qe->jobcomment;
  1930.         if (pp == NULL)
  1931.             pp = "";
  1932.         if (strlen(pp) > 255) {
  1933.             *(pp+255) = '\0';
  1934.             if (debugmode)
  1935.                 fprintf(stdout, "bwnfsd: [xdr_send_printq] jobcomment truncated to %s\n", pp);
  1936.         }
  1937.         if (!xdr_string(xdrsp, &pp, 255))
  1938.             return(0);
  1939.         qe = qe->next;
  1940.     }
  1941.     i = 0;
  1942.     if (!xdr_int(xdrsp,&i))
  1943.         return(0);
  1944.     return(1);
  1945. }
  1946.  
  1947. #ifdef SCO
  1948. #define SecureWare 1
  1949. #include <sys/security.h>
  1950. #include <sys/audit.h>
  1951. #include <prot.h>
  1952. #endif
  1953.  
  1954. char *
  1955. find_host(r_ip)
  1956.     unsigned long r_ip;
  1957. {
  1958. char *p;
  1959. unsigned long incomming_ip;
  1960. struct hostent *h;
  1961.  
  1962.     if (r_ip == my_ip)
  1963.         p = hostname;
  1964.     else {
  1965.         incomming_ip = ntohl(r_ip);
  1966.         h = gethostbyaddr((char *)&incomming_ip, 4, AF_INET);
  1967.         if (h == NULL) {
  1968.             sprintf(remote_host,"%u.%u.%u.%u",
  1969.                        (r_ip >> 24) & 0xff);
  1970.                        (r_ip >> 16) & 0xff,
  1971.                        (r_ip >>  8) & 0xff,
  1972.                        (r_ip      ) & 0xff,
  1973.             p = remote_host;
  1974.         } else
  1975.             p = h->h_name;
  1976.     }
  1977.     return(p);
  1978. }
  1979.  
  1980. struct user_cache_struct {
  1981.     char username[32];
  1982.     int uid, gid;
  1983.     char password[32];
  1984.     unsigned long successes;
  1985. } user_cache[NUM_USER_CACHE] = { 0 };
  1986.  
  1987. int cache_cycle=0;
  1988.  
  1989. void
  1990. add_cache(pw, p)
  1991.     struct passwd *pw;
  1992.     char *p;
  1993. {
  1994. int i,pos;
  1995. unsigned long smin= ~0L;
  1996.  
  1997.     pos = 0;
  1998.     cache_cycle = (cache_cycle+1) % NUM_USER_CACHE;
  1999.     for (i=0; i<NUM_USER_CACHE; i++)
  2000.         if ((user_cache[i].successes < smin) ||
  2001.             ((user_cache[i].successes == smin) && (i <= cache_cycle))) {
  2002.             pos = i;
  2003.             smin = user_cache[i].successes;
  2004.         }
  2005.     if (debugmode)
  2006.         fprintf(stdout, "bwnfsd: [addcache] <%s> added to position %d replacing <%s(%ld)>\n",
  2007.             pw->pw_name, pos, user_cache[pos].username, user_cache[pos].successes);
  2008.     strcpy(user_cache[pos].username, pw->pw_name);
  2009.     strcpy(user_cache[pos].password, p);
  2010.     user_cache[pos].uid = pw->pw_uid;
  2011.     user_cache[pos].gid = pw->pw_gid;
  2012.     user_cache[pos].successes = 1;
  2013. }
  2014.  
  2015. struct passwd *
  2016. getcache(request)
  2017.     struct auth_struct *request;
  2018. {
  2019. static struct passwd pas;
  2020. int i;
  2021.  
  2022.     for (i=0; i<NUM_USER_CACHE; i++) {
  2023.         if (strcmp(request->username, user_cache[i].username) == 0) {
  2024.             if (strcmp(crypt(request->password,user_cache[i].password), user_cache[i].password) == 0) {
  2025.                 pas.pw_name = user_cache[i].username;
  2026.                 pas.pw_uid = user_cache[i].uid;
  2027.                 pas.pw_gid = user_cache[i].gid;
  2028.                 user_cache[i].successes++;
  2029.                 if (debugmode)
  2030.                     fprintf(stdout, "bwnfsd: [getcache] <%s(%ld)> found in cache\n", request->username, user_cache[i].successes);
  2031.                 return(&pas);
  2032.             } else {
  2033.                 user_cache[i].username[0] = '\0';
  2034.                 user_cache[i].successes = 0;
  2035.                 if (debugmode)
  2036.                     fprintf(stdout, "bwnfsd: [getcache] <%s> wrong password in cache\n", request->username);
  2037.                 return(NULL);
  2038.             }
  2039.         }
  2040.     }
  2041.     return(NULL);
  2042. }
  2043.  
  2044. char *
  2045. reqname(req)
  2046.     int req;
  2047. {
  2048. static char buff[100];
  2049.  
  2050.     switch(req) {
  2051.     case NULLPROC:
  2052.         strcpy(buff, "Null Procedure");
  2053.         break;
  2054.     case SPOOL_INQUIRE:
  2055.         strcpy(buff, "Return fhandle of spool directory");
  2056.         break;
  2057.     case SPOOL_FILE:
  2058.         strcpy(buff, "Spool a file");
  2059.         break;
  2060.     case AUTHORIZE:
  2061.         strcpy(buff, "Authorize and return UID and GIDs");
  2062.         break;
  2063.     case GRP_NAME_TO_NUMB:
  2064.         strcpy(buff, "Convert group name to number");
  2065.         break;
  2066.     case GRP_TO_NUMBER:
  2067.         strcpy(buff, "Convert group number(s) to name(s)");
  2068.         break;
  2069.     case RETURN_HOST:
  2070.         strcpy(buff, "Convert IP to hostname");
  2071.         break;
  2072.     case UID_TO_NAME:
  2073.         strcpy(buff, "Convert UID(s) to name(s)");
  2074.         break;
  2075.     case NAME_TO_UID:
  2076.         strcpy(buff, "Convert name(s) to UID(s)");
  2077.         break;
  2078.     case SHARE:
  2079.         strcpy(buff, "DOS Share function");
  2080.         break;
  2081.     case UNSHARE:
  2082.         strcpy(buff, "DOS UnShare function");
  2083.         break;
  2084.     case ZAP_LOCKS:
  2085.         strcpy(buff, "Remove all locks on file by process");
  2086.         break;
  2087.     case LOCK:
  2088.         strcpy(buff, "DOS Lock request");
  2089.         break;
  2090.     case REMOVE:
  2091.         strcpy(buff, "Remove all locks/shares for PC");
  2092.         break;
  2093.     case UNLOCK:
  2094.         strcpy(buff, "DOS Unlock request");
  2095.         break;
  2096.     case GET_PRINTERS:
  2097.         strcpy(buff, "Get a list of printers");
  2098.         break;
  2099.     case GET_PRINTQ:
  2100.         strcpy(buff, "Get print queue entries and status");
  2101.         break;
  2102.     case CANCEL_PRJOB:
  2103.         strcpy(buff, "Cancel a print job");
  2104.         break;
  2105.     default:
  2106.         sprintf(buff, "Unknown request - %d", req);
  2107.         break;
  2108.     }
  2109.     return(buff);
  2110. }
  2111.  
  2112. /*
  2113.  *       The main RPC routine.
  2114.  */
  2115. void
  2116. create_spool(rqstp, transp)
  2117.     struct svc_req *rqstp;
  2118.     SVCXPRT *transp;
  2119. {
  2120. struct passwd *pw;
  2121. int i,j;
  2122. unsigned long r_ip, i_ip;
  2123. char *p;
  2124. #ifdef SHADW
  2125. struct spwd *sp;
  2126. #endif
  2127. #ifdef SCO
  2128. struct pr_passwd *prpw;
  2129. #endif
  2130.  
  2131.     if (debugmode)
  2132.         fprintf(stdout, "bwnfsd: [create_spool] called with %s\n", reqname(rqstp->rq_proc));
  2133.     switch(rqstp->rq_proc) {
  2134.     case NULLPROC:
  2135.         if (!svc_sendreply(transp, xdr_void, 0))
  2136.             if (debugmode)
  2137.                 fprintf(stdout, "bwnfsd: [nullproc] Can't reply to RPC call\n");
  2138.         return;
  2139.     case SPOOL_INQUIRE:
  2140.         if (!svc_sendreply(transp, xdr_file, &f))
  2141.             if (debugmode)
  2142.                 fprintf(stdout, "bwnfsd: [spool_inquire] Can't reply to RPC call\n");
  2143.         return;
  2144.     case SPOOL_FILE:
  2145.         if (!svc_getargs(transp,xdr_print, NULL)) {
  2146.             if (debugmode)
  2147.                 fprintf(stdout, "bwnfsd: [spool_file] svc_getargs request failed\n");
  2148.             svcerr_decode(transp);
  2149.             return;
  2150.         }
  2151.         i = 0;
  2152.         if (do_print == 0) {
  2153.             for (i=0; i<num_printers; i++)
  2154.                 if (strcmp(printers[i].queuename, printer) == 0) {
  2155.                     printers[i].lasttime = 0L;
  2156.                     break;
  2157.                 }
  2158.             if (debugmode)
  2159.                 fflush(stdout);
  2160.             if ((i=fork()) == 0) {
  2161.                 (void) signal(SIGHUP,SIG_IGN);
  2162.                 (void) signal(SIGINT,SIG_IGN);
  2163.                 (void) signal(SIGQUIT,SIG_IGN);
  2164. #ifdef SIGABRT
  2165.                 (void) signal(SIGABRT,SIG_IGN);
  2166. #endif
  2167.                 (void) signal(SIGTERM,SIG_IGN);
  2168.                 print_it(file1,printer,jobname);
  2169.                 exit(0);
  2170.             }
  2171.         }
  2172.         if (i != -1) {
  2173.             if (!svc_sendreply(transp, xdr_void, 0))
  2174.                 if (debugmode)
  2175.                     fprintf(stdout, "bwnfsd: [spool_file] Can't reply to RPC call\n");
  2176.         } else
  2177.             if (debugmode)
  2178.                 fprintf(stdout, "bwnfsd: [spool_file] Can't fork print process\n");
  2179.         return;
  2180.     case AUTHORIZE:
  2181.         if (!svc_getargs(transp,xdr_auth_request, &auth_request)) {
  2182.             if (debugmode)
  2183.                 fprintf(stdout, "bwnfsd: [authorize] svc_getargs request failed\n");
  2184.             svcerr_decode(transp);
  2185.             return;
  2186.         }
  2187.         if (auth_request.type == -1) {
  2188.             i = 1;
  2189.             if (!svc_sendreply(transp, xdr_int, &i))
  2190.                 if (debugmode)
  2191.                     fprintf(stdout, "bwnfsd: [authorize] (1) Can't reply to RPC call\n");
  2192.             return;
  2193.         }
  2194.         if (A_flag == 0) {
  2195.             if (s_flag == 0) {
  2196.                 if (ntohl(auth_request.ip) != my_ip) {
  2197.                     i = 1;
  2198.                     if (!svc_sendreply(transp, xdr_int, &i))
  2199.                         if (debugmode)
  2200.                             fprintf(stdout, "bwnfsd: [authorize] (2) Can't reply to RPC call\n");
  2201.                     return;
  2202.                 }
  2203.             } else {
  2204.                 for (i=0; i<ips_count; i++) {
  2205.                     if (((*(ips+i))->mask & ntohl(auth_request.ip)) == (*(ips+i))->ip) {
  2206.                         switch((*(ips+i))->type) {
  2207.                         case '+' :
  2208.                             i = ips_count+1;
  2209.                             break;
  2210.                         case '-' :
  2211.                             i = 1;
  2212.                             if (!svc_sendreply(transp, xdr_int, &i))
  2213.                                 if (debugmode)
  2214.                                     fprintf(stdout, "bwnfsd: [authorize] (3) Can't reply to RPC call\n");
  2215.                             return;
  2216.                         case '=' :
  2217.                             i_ip = (*(ips+i))->redirect_ip;
  2218.                             if (!svc_sendreply(transp, xdr_new_ip, &i_ip))
  2219.                                 if (debugmode)
  2220.                                     fprintf(stdout, "bwnfsd: [authorize] (4) Can't reply to RPC call\n");
  2221.                             return;
  2222.                         }
  2223.                     }
  2224.                 }
  2225.                 if (i == ips_count) {
  2226.                     i = 1;
  2227.                     if (!svc_sendreply(transp, xdr_int, &i))
  2228.                         if (debugmode)
  2229.                             fprintf(stdout, "bwnfsd: [authorize] (5) Can't reply to RPC call\n");
  2230.                     return;
  2231.                 }
  2232.             }
  2233.         }
  2234. #ifdef SCO
  2235.         if ((prpw=getprpwnam(auth_request.username)) == NULL) {
  2236.             if (debugmode)
  2237.                 fprintf(stdout, "bwnfsd: [authorize] getprpwnam failed\n");
  2238. auth_error:
  2239.             i = 1;
  2240.             if (!svc_sendreply(transp, xdr_int, &i))
  2241.                 if (debugmode)
  2242.                     fprintf(stdout, "bwnfsd: [authorize] (6) Can't reply to RPC call\n");
  2243.             return;
  2244.         }
  2245.         if (prpw->uflg.fg_lock && (prpw->ufld.fd_lock != 0))
  2246.             goto auth_error;
  2247.         i = prpw->ufld.fd_max_tries;
  2248.         if (i == 0)
  2249.             i = 5;
  2250.         if (prpw->ufld.fd_nlogins >= (short) i)
  2251.             goto auth_error;
  2252.         prpw->ufld.fd_encrypt[13] = '\0';
  2253.         if (strcmp(crypt(auth_request.password,prpw->ufld.fd_encrypt), prpw->ufld.fd_encrypt) != 0) {
  2254.             if (debugmode)
  2255.                 fprintf(stdout, "bwnfsd: [authorize] crypt(pwd)=%s doesn't match %s\n",crypt(auth_request.password,prpw->ufld.fd_encrypt), prpw->ufld.fd_encrypt);
  2256.             goto auth_error;
  2257.         }
  2258.         if ((pw=getpwnam(auth_request.username)) == NULL) {
  2259.             if (debugmode)
  2260.                 fprintf(stdout, "bwnfsd: [authorize] getpwnam failed\n");
  2261.             goto auth_error;
  2262.         }
  2263. #else
  2264.         if ((pw=getcache(&auth_request)) != NULL)
  2265.             goto got_pw;
  2266.         if ((pw=getpwnam(auth_request.username)) == NULL) {
  2267.             if (debugmode)
  2268.                 fprintf(stdout, "bwnfsd: [authorize] getpwnam failed\n");
  2269.             i = 1;
  2270.             if (!svc_sendreply(transp, xdr_int, &i))
  2271.                 if (debugmode)
  2272.                     fprintf(stdout, "bwnfsd: [authorize] (6) Can't reply to RPC call\n");
  2273.             return;
  2274.         }
  2275. #ifdef SHADW
  2276.         if ((sp=getspnam(auth_request.username)) == NULL) {
  2277.             if (debugmode)
  2278.                 fprintf(stdout, "bwnfsd: [authorize] getspnam request failed\n");
  2279.             i = 1;
  2280.             if (!svc_sendreply(transp, xdr_int, &i))
  2281.                 if (debugmode)
  2282.                     fprintf(stdout, "bwnfsd: [authorize] (7) Can't reply to RPC call\n");
  2283.             return;
  2284.         }
  2285.         p = sp->sp_pwdp;
  2286. #else
  2287.         p = pw->pw_passwd;
  2288. #endif
  2289.         if (strcmp(crypt(auth_request.password,p),p) != 0) {
  2290.             if (debugmode)
  2291.                 fprintf(stdout, "bwnfsd: [authorize] crypt(pwd)=%s doesn't match %s\n", crypt(auth_request.password,p), p);
  2292.             i = 1;
  2293.             if (!svc_sendreply(transp, xdr_int, &i))
  2294.                 if (debugmode)
  2295.                     fprintf(stdout, "bwnfsd: [authorize] (8) Can't reply to RPC call\n");
  2296.             return;
  2297.         }
  2298.         add_cache(pw, p);
  2299. #endif
  2300. got_pw:
  2301.         if (auth_request.type == 3) {
  2302.             for (i=0; i<num_printers; i++)
  2303.                 if (strcmp(printers[i].queuename,auth_request.device) == 0)
  2304.                     break;
  2305.             if (i == num_printers) {
  2306.                 if (debugmode)
  2307.                     fprintf(stdout, "bwnfsd: [authorize] Printer %s not found\n",auth_request.device);
  2308.                 i = 2;
  2309.                 if (!svc_sendreply(transp, xdr_int, &i))
  2310.                     if (debugmode)
  2311.                         fprintf(stdout, "bwnfsd: [authorize] (9) Can't reply to RPC call\n");
  2312.                 return;
  2313.             }
  2314. #ifdef CHECK_PRINTER_ACCESS
  2315.                if (!check_access(i,auth_request.username)) {
  2316.                 if (debugmode)
  2317.                     fprintf(stdout, "bwnfsd: [authorize] Not authorized for %s\n",auth_request.device);
  2318.                 i = 1;
  2319.                 if (!svc_sendreply(transp, xdr_int, &i))
  2320.                     if (debugmode)
  2321.                         fprintf(stdout, "bwnfsd: [authorize] (10) Can't reply to RPC call\n");
  2322.                 return;
  2323.             }
  2324. #endif
  2325.         }
  2326.         if (!svc_sendreply(transp, xdr_pw, pw))
  2327.             if (debugmode)
  2328.                 fprintf(stdout, "bwnfsd: [authorize] (11) Can't reply to RPC call\n");
  2329.         return;
  2330.     case GRP_NAME_TO_NUMB:
  2331.         if (!svc_getargs(transp,xdr_g_string, g_string)) {
  2332.             if (debugmode)
  2333.                 fprintf(stdout, "bwnfsd: [grp_name_to_numb] svc_getargs request failed\n");
  2334.             svcerr_decode(transp);
  2335.             return;
  2336.         }
  2337.         if (!svc_sendreply(transp, xdr_send_gid, g_string))
  2338.             if (debugmode)
  2339.                 fprintf(stdout, "bwnfsd: [grp_name_to_numb] Can't reply to RPC call\n");
  2340.         return;
  2341.     case GRP_TO_NUMBER:
  2342.         if (!svc_getargs(transp,xdr_ngids, lgids)) {
  2343.             if (debugmode)
  2344.                 fprintf(stdout, "bwnfsd: [grp_to_number] svc_getargs request failed\n");
  2345.             svcerr_decode(transp);
  2346.             return;
  2347.         }
  2348.         if (!svc_sendreply(transp, xdr_send_names, lgids))
  2349.             if (debugmode)
  2350.                 fprintf(stdout, "bwnfsd: [grp_to_number] Can't reply to RPC call\n");
  2351.         return;
  2352.     case RETURN_HOST:
  2353.         if (!svc_getargs(transp,xdr_int, &r_ip)) {
  2354.             if (debugmode)
  2355.                 fprintf(stdout, "bwnfsd: [return_host] svc_getargs request failed\n");
  2356.             svcerr_decode(transp);
  2357.             return;
  2358.         }
  2359.         p = find_host(r_ip);
  2360.         if (debugmode)
  2361.             fprintf(stdout, "bwnfsd: [return_host] remote = %s\n", p);
  2362.  
  2363.         if (!svc_sendreply(transp, xdr_g_string, p))
  2364.             if (debugmode)
  2365.                 fprintf(stdout, "bwnfsd: [return_host] Can't reply to RPC call\n");
  2366.         return;
  2367.     case UID_TO_NAME:
  2368.         if (!svc_getargs(transp,xdr_nuids, luids)) {
  2369.             if (debugmode)
  2370.                 fprintf(stdout, "bwnfsd: [uid_to_name] svc_getargs failed\n");
  2371.             svcerr_decode(transp);
  2372.             return;
  2373.         }
  2374.         if (!svc_sendreply(transp, xdr_send_usernames, luids))
  2375.             if (debugmode)
  2376.                 fprintf(stdout, "bwnfsd: [uid_to_name] Can't reply to RPC call\n");
  2377.         return;
  2378.     case NAME_TO_UID:
  2379.         if (!svc_getargs(transp, xdr_name_request, &name_request)) {
  2380.             if (debugmode)
  2381.                 fprintf(stdout, "bwnfsd: [name_to_uid] svc_getargs failed\n");
  2382.             svcerr_decode(transp);
  2383.             return;
  2384.         }
  2385.         if ((pw=getpwnam(name_request.usr_name)) == NULL) {
  2386.             i = 1;
  2387.             if (!svc_sendreply(transp, xdr_int, &i))
  2388.                 if (debugmode)
  2389.                     fprintf(stdout, "bwnfsd: [name_to_uid] (1) Can't reply to RPC call\n");
  2390.             return;
  2391.         }
  2392.         if (!svc_sendreply(transp, xdr_pw, pw))
  2393.             if (debugmode)
  2394.                 fprintf(stdout, "bwnfsd: [name_to_uid] (2) Can't reply to RPC call\n");
  2395.         return;
  2396.     case REMOVE:
  2397.         if (!svc_getargs(transp,xdr_get_lock_name,lock.name)) {
  2398.             if (debugmode)
  2399.                 fprintf(stdout, "bwnfsd: [remove] svc_getargs failed\n");
  2400.             svcerr_decode(transp);
  2401.             return;
  2402.         }
  2403.         process_lock_request((int) rqstp->rq_proc,lock.name,lock.fh,lock.access,
  2404.                      lock.mode,lock.offset,lock.length,lock.cookie,lock.lockowner);
  2405.         if (!svc_sendreply(transp,xdr_void,NULL))
  2406.             if (debugmode)
  2407.                 fprintf(stdout, "bwnfsd: [remove] Can't reply to RPC call\n");
  2408.         return;
  2409.     case SHARE:
  2410.     case UNSHARE:
  2411.         if (!svc_getargs(transp,xdr_share,&lock)) {
  2412.             if (debugmode)
  2413.                 fprintf(stdout, "bwnfsd: [%sshare] svc_getargs failed\n", rqstp->rq_proc==SHARE?"":"un");
  2414.             svcerr_decode(transp);
  2415.             return;
  2416.         }
  2417.         lock.stat = !process_lock_request((int) rqstp->rq_proc,lock.name,lock.fh,
  2418.                      lock.access,lock.mode,lock.offset,lock.length,lock.cookie,lock.lockowner);
  2419.         if (debugmode) {
  2420.             if (lock.stat)
  2421.                 fprintf(stdout, "bwnfsd: [%sshare] lock status = false\n", rqstp->rq_proc==SHARE?"":"un");
  2422.             else
  2423.                 fprintf(stdout, "bwnfsd: [%sshare] lock status = true\n", rqstp->rq_proc==SHARE?"":"un");
  2424.         }
  2425.         if (!svc_sendreply(transp,xdr_shareres,&lock))
  2426.             if (debugmode)
  2427.                 fprintf(stdout, "bwnfsd: [%sshare] Can't reply to RPC call\n", rqstp->rq_proc==SHARE?"":"un");
  2428.         return;
  2429.     case ZAP_LOCKS:
  2430.     case LOCK:
  2431.         lock.stat = svc_getargs(transp,xdr_lock,&lock);
  2432.         goto check_lock;
  2433.     case UNLOCK:
  2434.         lock.stat = svc_getargs(transp,xdr_unlock,&lock);
  2435.      check_lock:
  2436.         if (!lock.stat)
  2437.             if (!svc_getargs(transp,xdr_lock,&lock)) {
  2438.                 if (debugmode)
  2439.                     fprintf(stdout, "bwnfsd: [%slock] svc_getargs request failed\n", rqstp->rq_proc==LOCK?"":"un");
  2440.                 svcerr_decode(transp);
  2441.                 return;
  2442.             }
  2443.         lock.stat = !process_lock_request((int) rqstp->rq_proc,lock.name,lock.fh,
  2444.                      lock.access,lock.mode,lock.offset,lock.length,lock.cookie,lock.lockowner);
  2445.         if (debugmode)
  2446.             if (lock.stat)
  2447.                 fprintf(stdout, "bwnfsd: [%slock] lock status = false\n", rqstp->rq_proc==LOCK?"":rqstp->rq_proc==UNLOCK?"un":"zap");
  2448.             else
  2449.                 fprintf(stdout, "bwnfsd: [%slock] lock status = true\n", rqstp->rq_proc==LOCK?"":rqstp->rq_proc==UNLOCK?"un":"zap");
  2450.         if (!svc_sendreply(transp,xdr_res,&lock))
  2451.             if (debugmode)
  2452.                 fprintf(stdout, "bwnfsd: [%slock] Can't reply to RPC call\n", rqstp->rq_proc==LOCK?"":rqstp->rq_proc==UNLOCK?"un":"zap");
  2453.         return;
  2454.     case GET_PRINTERS:
  2455.         if (!svc_sendreply(transp, xdr_printers, NULL))
  2456.             if (debugmode)
  2457.                 fprintf(stdout, "bwnfsd: [get_printers] Can't reply to RPC call\n");
  2458.         return;
  2459.     case GET_PRINTQ:
  2460.         if (!svc_getargs(transp,xdr_get_printq,&printq)) {
  2461.             if (debugmode)
  2462.                 fprintf(stdout, "bwnfsd: [get_printq] svc_getargs failed\n");
  2463.             svcerr_decode(transp);
  2464.             return;
  2465.         }
  2466.         printq.printer_number = -1;
  2467.         for (i=0; i<num_printers; i++)
  2468.             if (strcmp(printers[i].queuename,printq.queuename) == 0) {
  2469.                 if (time(NULL) > (printers[i].lasttime+POLL_INTERVAL))
  2470.                     add_entries(i);
  2471.                 printq.printer_number = i;
  2472.                 break;
  2473.             }
  2474.         if (!svc_sendreply(transp,xdr_send_printq,&printq))
  2475.             if (debugmode)
  2476.                 fprintf(stdout, "bwnfsd: [get_printq] Can't reply to RPC call\n");
  2477.         return;
  2478.     case CANCEL_PRJOB:
  2479.         if (!svc_getargs(transp,xdr_cancel_job,&printq)) {
  2480.             if (debugmode)
  2481.                 fprintf(stdout, "bwnfsd: [cancel_prjob] svc_getargs failed\n");
  2482.             svcerr_decode(transp);
  2483.             return;
  2484.         }
  2485.         j = WN_BAD_QUEUE;
  2486.         for (i=0; i<num_printers; i++)
  2487.             if (strcmp(printers[i].queuename,printq.queuename) == 0) {
  2488.                 for (j=0; j<MAX_NUM_CANCEL_CACHE; j++)
  2489.                     if ((cancache[j].jobid == printq.printer_number) &&
  2490.                         (strcmp(cancache[j].username, printq.username) == 0) &&
  2491.                         (strcmp(cancache[j].queuename, printq.queuename) == 0)) {
  2492.                         j = cancache[j].response;
  2493.                         goto no_bloody_boolean_handy;
  2494.                     }
  2495.                 if ((j=cancel_printjob(i, printq.username, printq.printer_number)) == WN_SUCCESS)
  2496.                     printers[i].lasttime = 0L;
  2497.                 cancache[current_cache].jobid = printq.printer_number;
  2498.                 strcpy(cancache[current_cache].queuename, printq.queuename);
  2499.                 strcpy(cancache[current_cache].username, printq.username);
  2500.                 cancache[current_cache].response = j;
  2501.                 current_cache = ++current_cache%MAX_NUM_CANCEL_CACHE;
  2502.                 break;
  2503.             }
  2504. no_bloody_boolean_handy:
  2505.         if (!svc_sendreply(transp,xdr_int,&j))
  2506.             if (debugmode)
  2507.                 fprintf(stdout, "bwnfsd: [cancel_prjob] Can't reply to RPC call\n");
  2508.         return;
  2509.     default:
  2510.         svcerr_noproc(transp);
  2511.         return;
  2512.     }
  2513. }
  2514.  
  2515. static struct fhstatus {
  2516.     int status;
  2517.     char dir[32];
  2518. } mount_return;
  2519.  
  2520. /*
  2521.  *       Response from rpc.mountd for mount request of SPOOL directory.
  2522.  */
  2523. int
  2524. xdr_fhstatus(xdrsp, fhstat)
  2525.     XDR *xdrsp;
  2526.     struct fhstatus *fhstat;
  2527. {
  2528. int i;
  2529.  
  2530.     if (debugmode)
  2531.         fprintf(stdout, "bwnfsd: [xdr_fhstatus] called\n");
  2532.     if (!xdr_int(xdrsp, &fhstat->status))
  2533.         return(0);
  2534.     if (fhstat->status == 0)
  2535.         for (i=0; i<32 ; i+=4)
  2536.             if (!xdr_int(xdrsp, &(fhstat->dir[0])+i))
  2537.                 return(0);
  2538.     if (debugmode > 1)
  2539.         fprintf(stdout, "bwnfsd: [xdr_fhstatus] returns (1)\n");
  2540.     return(1);
  2541. }
  2542.  
  2543. static struct text_string {
  2544.     int length;
  2545.     char *dir;
  2546. } request_text;
  2547.  
  2548. /*
  2549.  *       Request to mount SPOOL directory.
  2550.  */
  2551. int
  2552. xdr_text(xdrsp, req)
  2553.     XDR *xdrsp;
  2554.     struct text_string *req;
  2555. {
  2556.     if (debugmode)
  2557.         fprintf(stdout, "bwnfsd: [xdr_text] mount request for %s\n", req->dir);
  2558.     if (!xdr_bytes(xdrsp, &req->dir, &req->length,255))
  2559.         return(0);
  2560.     if (debugmode > 1)
  2561.         fprintf(stdout, "bwnfsd: [xdr_text] returns (1)\n");
  2562.     return(1);
  2563. }
  2564.  
  2565.  
  2566. /*
  2567.  *       Use rpc.mountd to determine the fhandle of the spool directory,
  2568.  *       Can be replaced with extracted code from rpc.mountd.
  2569.  */
  2570. int get_mount(dir,directory)
  2571.     char *dir,*directory;
  2572. {
  2573. struct hostent *hp;
  2574. struct timeval pentry_timeout, total_timeout;
  2575. struct sockaddr_in server_addr;
  2576. int sock= RPC_ANYSOCK;
  2577. register CLIENT *client;
  2578. enum clnt_stat clnt_stat;
  2579.  
  2580.     if (debugmode)
  2581.         fprintf(stdout, "bwnfsd: [get_mount] called\n");
  2582.     if (debugmode > 1)
  2583.         fprintf(stdout, "bwnfsd: [get_mount] dir = \"%s\", directory = \"%s\"\n", dir, directory);
  2584.     request_text.length = strlen(directory);
  2585.     request_text.dir    = directory;
  2586.     if ((hp=gethostbyname(hostname)) == NULL) {
  2587.         fprintf(stdout, "bwnfsd: [get_mount] \"%s\" is not in the /etc/hosts file.\n", hostname);
  2588.         fprintf(stdout, "bwnfsd:             please enter it and re-run.\n");
  2589.         fflush(stdout);
  2590.         exit(-1);
  2591.     }
  2592.     pentry_timeout.tv_sec  = 3;
  2593.     pentry_timeout.tv_usec = 0;
  2594.     memcpy((caddr_t) &server_addr.sin_addr, hp->h_addr, hp->h_length);
  2595.     server_addr.sin_family = AF_INET;
  2596.     server_addr.sin_port   = 0;
  2597.     if ((client=(CLIENT *)clntudp_create(&server_addr, 100005L, 1L,pentry_timeout, &sock)) == NULL) {
  2598.         fprintf(stdout, "bwnfsd: [get_mount] clntupd_create failed\n");
  2599.         clnt_pcreateerror("clntudp_create");
  2600.         fflush(stdout);
  2601.         exit(-1);
  2602.     }
  2603.     if (bindresvport(sock, (struct sockaddr_in *) NULL))
  2604.         if (debugmode)
  2605.             fprintf(stdout, "bwnfsd: [get_mount] cannot allocate reserved port ... not critical.\n");
  2606.     client->cl_auth       = authunix_create_default();
  2607.     total_timeout.tv_sec  = 20;
  2608.     total_timeout.tv_usec = 0;
  2609.     clnt_stat             = clnt_call(client, 1L, xdr_text, &request_text,
  2610.                        xdr_fhstatus, &mount_return,
  2611.                        total_timeout);
  2612.     if (clnt_stat != RPC_SUCCESS) {
  2613.         fprintf(stdout, "bwnfsd: [get_mount] clnt_stat failed\n");
  2614.         clnt_perror(client,"rpc");
  2615.         fflush(stdout);
  2616.         exit(-1);
  2617.     }
  2618.     auth_destroy(client->cl_auth);
  2619.     clnt_destroy(client);
  2620.     if (mount_return.status == 0L)
  2621.         memcpy(dir, &mount_return.dir[0], 32);
  2622.     if (debugmode)
  2623.         fprintf(stdout, "bwnfsd: [get_mount] returns mount status %u\n",mount_return.status);
  2624.     return(mount_return.status);
  2625. }
  2626.  
  2627.  
  2628. /*
  2629.  *       Daemon should be killed with a simple KILL and not KILL -9 so
  2630.  *       that it may unmap itself
  2631.  */
  2632. Void
  2633. die(unused)
  2634.     int unused;
  2635. {
  2636.     fprintf(stdout, "bwnfsd: [die] Daemon is dying\n\n");
  2637.     fflush(stdout);
  2638.     (void) pmap_unset(BW_NFS_PROGRAM, BW_NFS_VERSION);
  2639.     exit(1);
  2640. }
  2641.  
  2642. void
  2643. ErrAndDie(fmt, str1, str2)
  2644.     char *fmt, *str1, *str2;
  2645. {
  2646.     fprintf(stdout, fmt, str1, str2);
  2647.     fflush(stdout);
  2648.     exit(-1);
  2649. }
  2650.  
  2651. int
  2652. main(argc,argv)
  2653.     int argc;
  2654.     char **argv;
  2655. {
  2656. SVCXPRT *transp;
  2657. char *p,*prog;
  2658. int i, child_pid;
  2659. struct hostent *hp;
  2660.  
  2661. #ifdef SCO
  2662.     set_auth_parameters(argc, argv);
  2663.     setluid(0);
  2664. #endif
  2665.  
  2666.     fprintf(stdout, "BWNFSD Authentication Daemon Vsn %s starting\n\n", VERSION);
  2667.     prog = argv[0];
  2668.     debugmode = 0;
  2669.     argc--;
  2670.     argv++;
  2671.  
  2672. another:
  2673.     if ((argc > 0) && (strcmp(*argv,"-A") == 0)) {
  2674.         argc--;
  2675.         argv++;
  2676.         A_flag=1;
  2677.         goto another;
  2678.     }
  2679.  
  2680.     if ((argc > 0) && (strcmp(*argv,"-d") == 0)) {
  2681.         argc--;
  2682.         argv++;
  2683.         debugmode++;
  2684.         goto another;
  2685.     }
  2686.  
  2687.     if ((argc > 0) && (strcmp(*argv,"-s") == 0)) {
  2688.         argc--;
  2689.         argv++;
  2690.         if (argc < 2)
  2691.             ErrAndDie("usage: %s [-A] [-d] [-s file] spool_area_mount_point\n", prog, NULL);
  2692.         read_ips(*argv);
  2693.         s_flag = 1;
  2694.         argc--;
  2695.         argv++;
  2696.         goto another;
  2697.     }
  2698.     if (argc != 1)
  2699.         ErrAndDie("usage: %s [-A] [-d] [-s file] spool_area_mount_point\n", prog, NULL);
  2700.  
  2701.     init_locks();
  2702.     hostname = (char *) malloc(255);
  2703.     (void) gethostname(hostname,255);
  2704.     if ((hp=gethostbyname(hostname)) == NULL)
  2705.         ErrAndDie("bwnfsd: host \"%s\" is not in the /etc/hosts file\nbwnfsd: Please add it to the file and restart %s\n", hostname, prog);
  2706.     memcpy((caddr_t) &my_ip, hp->h_addr, hp->h_length);
  2707.     if (get_mount(dir,*argv) != 0)
  2708.         ErrAndDie("bwnfsd: Spool area mount point %s could not be mounted.\nbwnfsd: Check that %s is in the /etc/exports file & world-writable\n", *argv, *argv);
  2709.  
  2710.     if (!debugmode) {
  2711. #ifdef SIGTTOU
  2712.         signal(SIGTTOU, SIG_IGN);
  2713. #endif
  2714. #ifdef SIGTTIN
  2715.         signal(SIGTTIN, SIG_IGN);
  2716. #endif
  2717. #ifdef SIGTSTP
  2718.         signal(SIGTSTP, SIG_IGN);
  2719. #endif
  2720.         if ((child_pid=fork()) > 0)
  2721.             exit(0);
  2722.         if (child_pid < 0)
  2723.             ErrAndDie("bwnfsd: Unable to detach process\n", NULL, NULL);
  2724. #ifdef SYSV_PGRP
  2725.         if (setpgrp() == -1)
  2726. #else
  2727.         if (setpgrp(0, 0) == -1)
  2728. #endif
  2729.             ErrAndDie("bwnfsd: [main] Can't change process group\n", NULL, NULL);
  2730. #ifdef SIGTSTP
  2731. #ifdef TIOCNOTTY
  2732.         if ((i=open("/dev/tty", O_RDWR)) >= 0) {
  2733.            ioctl(i, TIOCNOTTY, NULL);
  2734.            close(i);
  2735.         }
  2736. #endif
  2737. #else
  2738.         signal(SIGHUP, SIG_IGN);
  2739.         if ((child_pid=fork()) > 0)
  2740.             exit(0);
  2741.         if (child_pid < 0)
  2742.             ErrAndDie("bwnfsd: [main] Unable to detach second process\n", NULL, NULL);
  2743. #endif
  2744. #ifndef NOFILE
  2745. #define NOFILE 10
  2746. #endif
  2747.         for (i=0; i<NOFILE; i++)
  2748.             close(i);
  2749.         errno = 0;
  2750.         chdir("/");
  2751.         umask(0);
  2752.  
  2753.         if ((i=open("/dev/null", O_RDWR)) < 0)
  2754.             ErrAndDie("bwnfsd: [main] Unable to map handles\n", NULL, NULL);
  2755.         dup2(i, 4);
  2756.         close(i);
  2757.         dup2(4, 0);
  2758.         dup2(4, 1);
  2759.         dup2(4, 2);
  2760.         close(4);
  2761.     }
  2762.  
  2763.     if (determine_print_command() == 0)
  2764.         ErrAndDie("bwnfsd: [main] Unable to determine print command\n", NULL, NULL);
  2765.     p = strcpy(spool_dir,*argv) + strlen(*argv);
  2766.     if (*(p-1) == '/')
  2767.         *(--p) = '\0';
  2768.     get_printers();
  2769.     get_groups();
  2770.     f.status     = 0;
  2771.     f.dir_size   = 32;
  2772.     f.dir_handle = dir;
  2773.  
  2774.     transp = (SVCXPRT *)svcudp_create(RPC_ANYSOCK);
  2775.     if (transp == NULL)
  2776.         ErrAndDie("bwnfsd: [main] Unable to create an RPC server\n", NULL, NULL);
  2777.     (void) pmap_unset(BW_NFS_PROGRAM, BW_NFS_VERSION);
  2778.     if (!svc_register(transp,BW_NFS_PROGRAM, BW_NFS_VERSION,create_spool, IPPROTO_UDP))
  2779.         ErrAndDie("bwnfsd: [main] Can't register BWNFSD service\n", NULL, NULL);
  2780.     (void) signal(SIGHUP, clear);
  2781.     (void) signal(SIGINT, die);
  2782.     (void) signal(SIGQUIT, die);
  2783. #ifdef SIGABRT
  2784.     (void) signal(SIGABRT, die);
  2785. #endif
  2786.     (void) signal(SIGTERM, die);
  2787. #ifdef SIGCHLD
  2788.     (void) signal(SIGCHLD, free_child);
  2789. #endif
  2790. #ifdef SIGCLD
  2791. #ifndef SIGTSTP
  2792.     (void) signal(SIGCLD, SIG_IGN);
  2793. #else
  2794.     (void) signal(SIGCLD, free_child);
  2795. #endif
  2796. #endif
  2797.     svc_run();
  2798.     fprintf(stdout, "bwnfsd: [main] svc_run returned!\n");
  2799.     fflush(stdout);
  2800.     exit(1);
  2801.     return(1); /* for the compulsive compilers */
  2802. }
  2803.