auth.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:19k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * auth.c
  4.  *   Routines to handle network authentication
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/libpq/auth.c,v 1.37 1999/05/26 12:55:15 momjian Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. /*
  15.  * INTERFACE ROUTINES
  16.  *
  17.  *    backend (postmaster) routines:
  18.  * be_recvauth receive authentication information
  19.  */
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <sys/param.h> /* for MAXHOSTNAMELEN on most */
  23. #ifndef  MAXHOSTNAMELEN
  24. #include <netdb.h> /* for MAXHOSTNAMELEN on some */
  25. #endif
  26. #include <pwd.h>
  27. #include <ctype.h> /* isspace() declaration */
  28. #include <sys/types.h> /* needed by in.h on Ultrix */
  29. #include <netinet/in.h>
  30. #include <arpa/inet.h>
  31. #include <postgres.h>
  32. #include <miscadmin.h>
  33. #include <libpq/auth.h>
  34. #include <libpq/libpq.h>
  35. #include <libpq/hba.h>
  36. #include <libpq/password.h>
  37. #include <libpq/crypt.h>
  38. static void sendAuthRequest(Port *port, AuthRequest areq, PacketDoneProc handler);
  39. static int handle_done_auth(void *arg, PacketLen len, void *pkt);
  40. static int handle_krb4_auth(void *arg, PacketLen len, void *pkt);
  41. static int handle_krb5_auth(void *arg, PacketLen len, void *pkt);
  42. static int handle_password_auth(void *arg, PacketLen len, void *pkt);
  43. static int readPasswordPacket(void *arg, PacketLen len, void *pkt);
  44. static int pg_passwordv0_recvauth(void *arg, PacketLen len, void *pkt);
  45. static int checkPassword(Port *port, char *user, char *password);
  46. static int old_be_recvauth(Port *port);
  47. static int map_old_to_new(Port *port, UserAuth old, int status);
  48. static void auth_failed(Port *port);
  49. #ifdef KRB4
  50. /* This has to be ifdef'd out because krb.h does exist.  This needs
  51.    to be fixed.
  52. */
  53. /*----------------------------------------------------------------
  54.  * MIT Kerberos authentication system - protocol version 4
  55.  *----------------------------------------------------------------
  56.  */
  57. #include <krb.h>
  58. /*
  59.  * pg_krb4_recvauth -- server routine to receive authentication information
  60.  *    from the client
  61.  *
  62.  * Nothing unusual here, except that we compare the username obtained from
  63.  * the client's setup packet to the authenticated name.  (We have to retain
  64.  * the name in the setup packet since we have to retain the ability to handle
  65.  * unauthenticated connections.)
  66.  */
  67. static int
  68. pg_krb4_recvauth(Port *port)
  69. {
  70. long krbopts = 0; /* one-way authentication */
  71. KTEXT_ST clttkt;
  72. char instance[INST_SZ + 1],
  73. version[KRB_SENDAUTH_VLEN + 1];
  74. AUTH_DAT auth_data;
  75. Key_schedule key_sched;
  76. int status;
  77. strcpy(instance, "*"); /* don't care, but arg gets expanded
  78.  * anyway */
  79. status = krb_recvauth(krbopts,
  80.   port->sock,
  81.   &clttkt,
  82.   PG_KRB_SRVNAM,
  83.   instance,
  84.   &port->raddr.in,
  85.   &port->laddr.in,
  86.   &auth_data,
  87.   PG_KRB_SRVTAB,
  88.   key_sched,
  89.   version);
  90. if (status != KSUCCESS)
  91. {
  92. snprintf(PQerrormsg, ERROR_MSG_LENGTH,
  93.   "pg_krb4_recvauth: kerberos error: %sn", krb_err_txt[status]);
  94. fputs(PQerrormsg, stderr);
  95. pqdebug("%s", PQerrormsg);
  96. return STATUS_ERROR;
  97. }
  98. if (strncmp(version, PG_KRB4_VERSION, KRB_SENDAUTH_VLEN))
  99. {
  100. snprintf(PQerrormsg, ERROR_MSG_LENGTH,
  101.  "pg_krb4_recvauth: protocol version != "%s"n", PG_KRB4_VERSION);
  102. fputs(PQerrormsg, stderr);
  103. pqdebug("%s", PQerrormsg);
  104. return STATUS_ERROR;
  105. }
  106. if (strncmp(port->user, auth_data.pname, SM_USER))
  107. {
  108. snprintf(PQerrormsg, ERROR_MSG_LENGTH,
  109.  "pg_krb4_recvauth: name "%s" != "%s"n",
  110.  port->user, auth_data.pname);
  111. fputs(PQerrormsg, stderr);
  112. pqdebug("%s", PQerrormsg);
  113. return STATUS_ERROR;
  114. }
  115. return STATUS_OK;
  116. }
  117. #else
  118. static int
  119. pg_krb4_recvauth(Port *port)
  120. {
  121. snprintf(PQerrormsg, ERROR_MSG_LENGTH,
  122.  "pg_krb4_recvauth: Kerberos not implemented on this server.n");
  123. fputs(PQerrormsg, stderr);
  124. pqdebug("%s", PQerrormsg);
  125. return STATUS_ERROR;
  126. }
  127. #endif  /* KRB4 */
  128. #ifdef KRB5
  129. /* This needs to be ifdef'd out because krb5.h doesn't exist.  This needs
  130.    to be fixed.
  131. */
  132. /*----------------------------------------------------------------
  133.  * MIT Kerberos authentication system - protocol version 5
  134.  *----------------------------------------------------------------
  135.  */
  136. #include <krb5/krb5.h>
  137. /*
  138.  * pg_an_to_ln -- return the local name corresponding to an authentication
  139.  *   name
  140.  *
  141.  * XXX Assumes that the first aname component is the user name.  This is NOT
  142.  *    necessarily so, since an aname can actually be something out of your
  143.  *    worst X.400 nightmare, like
  144.  *   ORGANIZATION=U. C. Berkeley/NAME=Paul M. Aoki@CS.BERKELEY.EDU
  145.  *    Note that the MIT an_to_ln code does the same thing if you don't
  146.  *    provide an aname mapping database...it may be a better idea to use
  147.  *    krb5_an_to_ln, except that it punts if multiple components are found,
  148.  *    and we can't afford to punt.
  149.  */
  150. static char *
  151. pg_an_to_ln(char *aname)
  152. {
  153. char    *p;
  154. if ((p = strchr(aname, '/')) || (p = strchr(aname, '@')))
  155. *p = '';
  156. return aname;
  157. }
  158. /*
  159.  * pg_krb5_recvauth -- server routine to receive authentication information
  160.  *    from the client
  161.  *
  162.  * We still need to compare the username obtained from the client's setup
  163.  * packet to the authenticated name, as described in pg_krb4_recvauth. This
  164.  * is a bit more problematic in v5, as described above in pg_an_to_ln.
  165.  *
  166.  * In addition, as described above in pg_krb5_sendauth, we still need to
  167.  * canonicalize the server name v4-style before constructing a principal
  168.  * from it.  Again, this is kind of iffy.
  169.  *
  170.  * Finally, we need to tangle with the fact that v5 doesn't let you explicitly
  171.  * set server keytab file names -- you have to feed lower-level routines a
  172.  * function to retrieve the contents of a keytab, along with a single argument
  173.  * that allows them to open the keytab.  We assume that a server keytab is
  174.  * always a real file so we can allow people to specify their own filenames.
  175.  * (This is important because the POSTGRES keytab needs to be readable by
  176.  * non-root users/groups; the v4 tools used to force you do dump a whole
  177.  * host's worth of keys into a file, effectively forcing you to use one file,
  178.  * but kdb5_edit allows you to select which principals to dump.  Yay!)
  179.  */
  180. static int
  181. pg_krb5_recvauth(Port *port)
  182. {
  183. char servbuf[MAXHOSTNAMELEN + 1 +
  184. sizeof(PG_KRB_SRVNAM)];
  185. char    *hostp,
  186.    *kusername = (char *) NULL;
  187. krb5_error_code code;
  188. krb5_principal client,
  189. server;
  190. krb5_address sender_addr;
  191. krb5_rdreq_key_proc keyproc = (krb5_rdreq_key_proc) NULL;
  192. krb5_pointer keyprocarg = (krb5_pointer) NULL;
  193. /*
  194.  * Set up server side -- since we have no ticket file to make this
  195.  * easy, we construct our own name and parse it.  See note on
  196.  * canonicalization above.
  197.  */
  198. strcpy(servbuf, PG_KRB_SRVNAM);
  199. *(hostp = servbuf + (sizeof(PG_KRB_SRVNAM) - 1)) = '/';
  200. if (gethostname(++hostp, MAXHOSTNAMELEN) < 0)
  201. strcpy(hostp, "localhost");
  202. if (hostp = strchr(hostp, '.'))
  203. *hostp = '';
  204. if (code = krb5_parse_name(servbuf, &server))
  205. {
  206. snprintf(PQerrormsg, ERROR_MSG_LENGTH,
  207. "pg_krb5_recvauth: Kerberos error %d in krb5_parse_namen", code);
  208. com_err("pg_krb5_recvauth", code, "in krb5_parse_name");
  209. return STATUS_ERROR;
  210. }
  211. /*
  212.  * krb5_sendauth needs this to verify the address in the client
  213.  * authenticator.
  214.  */
  215. sender_addr.addrtype = port->raddr.in.sin_family;
  216. sender_addr.length = sizeof(port->raddr.in.sin_addr);
  217. sender_addr.contents = (krb5_octet *) & (port->raddr.in.sin_addr);
  218. if (strcmp(PG_KRB_SRVTAB, ""))
  219. {
  220. keyproc = krb5_kt_read_service_key;
  221. keyprocarg = PG_KRB_SRVTAB;
  222. }
  223. if (code = krb5_recvauth((krb5_pointer) & port->sock,
  224.  PG_KRB5_VERSION,
  225.  server,
  226.  &sender_addr,
  227.  (krb5_pointer) NULL,
  228.  keyproc,
  229.  keyprocarg,
  230.  (char *) NULL,
  231.  (krb5_int32 *) NULL,
  232.  &client,
  233.  (krb5_ticket **) NULL,
  234.  (krb5_authenticator **) NULL))
  235. {
  236. snprintf(PQerrormsg, ERROR_MSG_LENGTH,
  237.  "pg_krb5_recvauth: Kerberos error %d in krb5_recvauthn", code);
  238. com_err("pg_krb5_recvauth", code, "in krb5_recvauth");
  239. krb5_free_principal(server);
  240. return STATUS_ERROR;
  241. }
  242. krb5_free_principal(server);
  243. /*
  244.  * The "client" structure comes out of the ticket and is therefore
  245.  * authenticated.  Use it to check the username obtained from the
  246.  * postmaster startup packet.
  247.  */
  248. if ((code = krb5_unparse_name(client, &kusername)))
  249. {
  250. snprintf(PQerrormsg, ERROR_MSG_LENGTH,
  251.  "pg_krb5_recvauth: Kerberos error %d in krb5_unparse_namen", code);
  252. com_err("pg_krb5_recvauth", code, "in krb5_unparse_name");
  253. krb5_free_principal(client);
  254. return STATUS_ERROR;
  255. }
  256. krb5_free_principal(client);
  257. if (!kusername)
  258. {
  259. snprintf(PQerrormsg, ERROR_MSG_LENGTH,
  260.  "pg_krb5_recvauth: could not decode usernamen");
  261. fputs(PQerrormsg, stderr);
  262. pqdebug("%s", PQerrormsg);
  263. return STATUS_ERROR;
  264. }
  265. kusername = pg_an_to_ln(kusername);
  266. if (strncmp(username, kusername, SM_USER))
  267. {
  268. snprintf(PQerrormsg, ERROR_MSG_LENGTH,
  269.  "pg_krb5_recvauth: name "%s" != "%s"n", port->user, kusername);
  270. fputs(PQerrormsg, stderr);
  271. pqdebug("%s", PQerrormsg);
  272. pfree(kusername);
  273. return STATUS_ERROR;
  274. }
  275. pfree(kusername);
  276. return STATUS_OK;
  277. }
  278. #else
  279. static int
  280. pg_krb5_recvauth(Port *port)
  281. {
  282. snprintf(PQerrormsg, ERROR_MSG_LENGTH,
  283.  "pg_krb5_recvauth: Kerberos not implemented on this server.n");
  284. fputs(PQerrormsg, stderr);
  285. pqdebug("%s", PQerrormsg);
  286. return STATUS_ERROR;
  287. }
  288. #endif  /* KRB5 */
  289. /*
  290.  * Handle a v0 password packet.
  291.  */
  292. static int
  293. pg_passwordv0_recvauth(void *arg, PacketLen len, void *pkt)
  294. {
  295. Port    *port;
  296. PasswordPacketV0 *pp;
  297. char    *user,
  298.    *password,
  299.    *cp,
  300.    *start;
  301. port = (Port *) arg;
  302. pp = (PasswordPacketV0 *) pkt;
  303. /*
  304.  * The packet is supposed to comprise the user name and the password
  305.  * as C strings.  Be careful the check that this is the case.
  306.  */
  307. user = password = NULL;
  308. len -= sizeof(pp->unused);
  309. cp = start = pp->data;
  310. while (len-- > 0)
  311. if (*cp++ == '')
  312. {
  313. if (user == NULL)
  314. user = start;
  315. else
  316. {
  317. password = start;
  318. break;
  319. }
  320. start = cp;
  321. }
  322. if (user == NULL || password == NULL)
  323. {
  324. snprintf(PQerrormsg, ERROR_MSG_LENGTH,
  325.  "pg_password_recvauth: badly formed password packet.n");
  326. fputs(PQerrormsg, stderr);
  327. pqdebug("%s", PQerrormsg);
  328. auth_failed(port);
  329. }
  330. else
  331. {
  332. int status;
  333. UserAuth saved;
  334. /* Check the password. */
  335. saved = port->auth_method;
  336. port->auth_method = uaPassword;
  337. status = checkPassword(port, user, password);
  338. port->auth_method = saved;
  339. /* Adjust the result if necessary. */
  340. if (map_old_to_new(port, uaPassword, status) != STATUS_OK)
  341. auth_failed(port);
  342. }
  343. return STATUS_OK; /* don't close the connection yet */
  344. }
  345. /*
  346.  * Tell the user the authentication failed, but not (much about) why.
  347.  *
  348.  * There is a tradeoff here between security concerns and making life
  349.  * unnecessarily difficult for legitimate users.  We would not, for example,
  350.  * want to report the password we were expecting to receive...
  351.  * But it seems useful to report the username and authorization method
  352.  * in use, and these are items that must be presumed known to an attacker
  353.  * anyway.
  354.  * Note that many sorts of failure report additional information in the
  355.  * postmaster log, which we hope is only readable by good guys.
  356.  */
  357. static void
  358. auth_failed(Port *port)
  359. {
  360. char buffer[512];
  361. const char *authmethod = "Unknown auth method:";
  362. switch (port->auth_method)
  363. {
  364. case uaReject:
  365. authmethod = "Rejected host:";
  366. break;
  367. case uaKrb4:
  368. authmethod = "Kerberos4";
  369. break;
  370. case uaKrb5:
  371. authmethod = "Kerberos5";
  372. break;
  373. case uaTrust:
  374. authmethod = "Trusted";
  375. break;
  376. case uaIdent:
  377. authmethod = "IDENT";
  378. break;
  379. case uaPassword:
  380. authmethod = "Password";
  381. break;
  382. case uaCrypt:
  383. authmethod = "Password";
  384. break;
  385. }
  386. sprintf(buffer, "%s authentication failed for user '%s'",
  387. authmethod, port->user);
  388. PacketSendError(&port->pktInfo, buffer);
  389. }
  390. /*
  391.  * be_recvauth -- server demux routine for incoming authentication information
  392.  */
  393. void
  394. be_recvauth(Port *port)
  395. {
  396. /*
  397.  * Get the authentication method to use for this frontend/database
  398.  * combination.  Note: a failure return indicates a problem with the
  399.  * hba config file, not with the request.  hba.c should have dropped
  400.  * an error message into the postmaster logfile if it failed.
  401.  */
  402. if (hba_getauthmethod(&port->raddr, port->user, port->database,
  403. port->auth_arg, &port->auth_method) != STATUS_OK)
  404. PacketSendError(&port->pktInfo,
  405. "Missing or erroneous pg_hba.conf file, see postmaster log for details");
  406. else if (PG_PROTOCOL_MAJOR(port->proto) == 0)
  407. {
  408. /* Handle old style authentication. */
  409. if (old_be_recvauth(port) != STATUS_OK)
  410. auth_failed(port);
  411. }
  412. else
  413. {
  414. /* Handle new style authentication. */
  415. AuthRequest areq = AUTH_REQ_OK;
  416. PacketDoneProc auth_handler = NULL;
  417. switch (port->auth_method)
  418. {
  419. case uaReject:
  420. /*
  421.  * This could have come from an explicit "reject" entry in
  422.  * pg_hba.conf, but more likely it means there was no
  423.  * matching entry. Take pity on the poor user and issue a
  424.  * helpful error message.  NOTE: this is not a security
  425.  * breach, because all the info reported here is known at
  426.  * the frontend and must be assumed known to bad guys.
  427.  * We're merely helping out the less clueful good guys.
  428.  * NOTE 2: libpq-be.h defines the maximum error message
  429.  * length as 99 characters.  It probably wouldn't hurt
  430.  * anything to increase it, but there might be some client
  431.  * out there that will fail.  So, be terse.
  432.  */
  433. {
  434. char buffer[512];
  435. const char *hostinfo = "localhost";
  436. if (port->raddr.sa.sa_family == AF_INET)
  437. hostinfo = inet_ntoa(port->raddr.in.sin_addr);
  438. sprintf(buffer,
  439. "No pg_hba.conf entry for host %s, user %s, database %s",
  440. hostinfo, port->user, port->database);
  441. PacketSendError(&port->pktInfo, buffer);
  442. return;
  443. }
  444. break;
  445. case uaKrb4:
  446. areq = AUTH_REQ_KRB4;
  447. auth_handler = handle_krb4_auth;
  448. break;
  449. case uaKrb5:
  450. areq = AUTH_REQ_KRB5;
  451. auth_handler = handle_krb5_auth;
  452. break;
  453. case uaTrust:
  454. areq = AUTH_REQ_OK;
  455. auth_handler = handle_done_auth;
  456. break;
  457. case uaIdent:
  458. if (authident(&port->raddr.in, &port->laddr.in,
  459.   port->user, port->auth_arg) == STATUS_OK)
  460. {
  461. areq = AUTH_REQ_OK;
  462. auth_handler = handle_done_auth;
  463. }
  464. break;
  465. case uaPassword:
  466. areq = AUTH_REQ_PASSWORD;
  467. auth_handler = handle_password_auth;
  468. break;
  469. case uaCrypt:
  470. areq = AUTH_REQ_CRYPT;
  471. auth_handler = handle_password_auth;
  472. break;
  473. }
  474. /* Tell the frontend what we want next. */
  475. if (auth_handler != NULL)
  476. sendAuthRequest(port, areq, auth_handler);
  477. else
  478. auth_failed(port);
  479. }
  480. }
  481. /*
  482.  * Send an authentication request packet to the frontend.
  483.  */
  484. static void
  485. sendAuthRequest(Port *port, AuthRequest areq, PacketDoneProc handler)
  486. {
  487. char    *dp,
  488.    *sp;
  489. int i;
  490. uint32 net_areq;
  491. /* Convert to a byte stream. */
  492. net_areq = htonl(areq);
  493. dp = port->pktInfo.pkt.ar.data;
  494. sp = (char *) &net_areq;
  495. *dp++ = 'R';
  496. for (i = 1; i <= 4; ++i)
  497. *dp++ = *sp++;
  498. /* Add the salt for encrypted passwords. */
  499. if (areq == AUTH_REQ_CRYPT)
  500. {
  501. *dp++ = port->salt[0];
  502. *dp++ = port->salt[1];
  503. i += 2;
  504. }
  505. PacketSendSetup(&port->pktInfo, i, handler, (void *) port);
  506. }
  507. /*
  508.  * Called when we have told the front end that it is authorised.
  509.  */
  510. static int
  511. handle_done_auth(void *arg, PacketLen len, void *pkt)
  512. {
  513. /*
  514.  * Don't generate any more traffic.  This will cause the backend to
  515.  * start.
  516.  */
  517. return STATUS_OK;
  518. }
  519. /*
  520.  * Called when we have told the front end that it should use Kerberos V4
  521.  * authentication.
  522.  */
  523. static int
  524. handle_krb4_auth(void *arg, PacketLen len, void *pkt)
  525. {
  526. Port    *port = (Port *) arg;
  527. if (pg_krb4_recvauth(port) != STATUS_OK)
  528. auth_failed(port);
  529. else
  530. sendAuthRequest(port, AUTH_REQ_OK, handle_done_auth);
  531. return STATUS_OK;
  532. }
  533. /*
  534.  * Called when we have told the front end that it should use Kerberos V5
  535.  * authentication.
  536.  */
  537. static int
  538. handle_krb5_auth(void *arg, PacketLen len, void *pkt)
  539. {
  540. Port    *port = (Port *) arg;
  541. if (pg_krb5_recvauth(port) != STATUS_OK)
  542. auth_failed(port);
  543. else
  544. sendAuthRequest(port, AUTH_REQ_OK, handle_done_auth);
  545. return STATUS_OK;
  546. }
  547. /*
  548.  * Called when we have told the front end that it should use password
  549.  * authentication.
  550.  */
  551. static int
  552. handle_password_auth(void *arg, PacketLen len, void *pkt)
  553. {
  554. Port    *port = (Port *) arg;
  555. /* Set up the read of the password packet. */
  556. PacketReceiveSetup(&port->pktInfo, readPasswordPacket, (void *) port);
  557. return STATUS_OK;
  558. }
  559. /*
  560.  * Called when we have received the password packet.
  561.  */
  562. static int
  563. readPasswordPacket(void *arg, PacketLen len, void *pkt)
  564. {
  565. char password[sizeof(PasswordPacket) + 1];
  566. Port    *port = (Port *) arg;
  567. /* Silently truncate a password that is too big. */
  568. if (len > sizeof(PasswordPacket))
  569. len = sizeof(PasswordPacket);
  570. StrNCpy(password, ((PasswordPacket *) pkt)->passwd, len);
  571. if (checkPassword(port, port->user, password) != STATUS_OK)
  572. auth_failed(port);
  573. else
  574. sendAuthRequest(port, AUTH_REQ_OK, handle_done_auth);
  575. return STATUS_OK; /* don't close the connection yet */
  576. }
  577. /*
  578.  * Use the local flat password file if clear passwords are used and the file is
  579.  * specified.  Otherwise use the password in the pg_shadow table, encrypted or
  580.  * not.
  581.  */
  582. static int
  583. checkPassword(Port *port, char *user, char *password)
  584. {
  585. if (port->auth_method == uaPassword && port->auth_arg[0] != '')
  586. return verify_password(port->auth_arg, user, password);
  587. return crypt_verify(port, user, password);
  588. }
  589. /*
  590.  * Server demux routine for incoming authentication information for protocol
  591.  * version 0.
  592.  */
  593. static int
  594. old_be_recvauth(Port *port)
  595. {
  596. int status;
  597. MsgType msgtype = (MsgType) port->proto;
  598. /* Handle the authentication that's offered. */
  599. switch (msgtype)
  600. {
  601. case STARTUP_KRB4_MSG:
  602. status = map_old_to_new(port, uaKrb4, pg_krb4_recvauth(port));
  603. break;
  604. case STARTUP_KRB5_MSG:
  605. status = map_old_to_new(port, uaKrb5, pg_krb5_recvauth(port));
  606. break;
  607. case STARTUP_MSG:
  608. status = map_old_to_new(port, uaTrust, STATUS_OK);
  609. break;
  610. case STARTUP_PASSWORD_MSG:
  611. PacketReceiveSetup(&port->pktInfo, pg_passwordv0_recvauth,
  612.    (void *) port);
  613. return STATUS_OK;
  614. default:
  615. fprintf(stderr, "Invalid startup message type: %un", msgtype);
  616. return STATUS_OK;
  617. }
  618. return status;
  619. }
  620. /*
  621.  * The old style authentication has been done. Modify the result of this (eg.
  622.  * allow the connection anyway, disallow it anyway, or use the result)
  623.  * depending on what authentication we really want to use.
  624.  */
  625. static int
  626. map_old_to_new(Port *port, UserAuth old, int status)
  627. {
  628. switch (port->auth_method)
  629. {
  630. case uaCrypt:
  631. case uaReject:
  632. status = STATUS_ERROR;
  633. break;
  634. case uaKrb4:
  635. if (old != uaKrb4)
  636. status = STATUS_ERROR;
  637. break;
  638. case uaKrb5:
  639. if (old != uaKrb5)
  640. status = STATUS_ERROR;
  641. break;
  642. case uaTrust:
  643. status = STATUS_OK;
  644. break;
  645. case uaIdent:
  646. status = authident(&port->raddr.in, &port->laddr.in,
  647.    port->user, port->auth_arg);
  648. break;
  649. case uaPassword:
  650. if (old != uaPassword)
  651. status = STATUS_ERROR;
  652. break;
  653. }
  654. return status;
  655. }