PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
fe-auth.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netdb.h>
#include <pwd.h>
#include "common/md5.h"
#include "libpq-fe.h"
#include "libpq/scram.h"
#include "fe-auth.h"
Include dependency graph for fe-auth.c:

Go to the source code of this file.

Functions

static bool pg_SASL_init (PGconn *conn, const char *auth_mechanism)
 
static int pg_SASL_exchange (PGconn *conn)
 
static int pg_local_sendauth (PGconn *conn)
 
static int pg_password_sendauth (PGconn *conn, const char *password, AuthRequest areq)
 
int pg_fe_sendauth (AuthRequest areq, PGconn *conn)
 
char * pg_fe_getauthname (PQExpBuffer errorMessage)
 
char * PQencryptPassword (const char *passwd, const char *user)
 

Function Documentation

char* pg_fe_getauthname ( PQExpBuffer  errorMessage)

Definition at line 846 of file fe-auth.c.

References libpq_gettext, name, NULL, pglock_thread, pgunlock_thread, pqGetpwuid(), pqStrerror(), printfPQExpBuffer(), result, and username.

Referenced by connectOptions2(), and conninfo_add_defaults().

847 {
848  char *result = NULL;
849  const char *name = NULL;
850 
851 #ifdef WIN32
852  /* Microsoft recommends buffer size of UNLEN+1, where UNLEN = 256 */
853  char username[256 + 1];
854  DWORD namesize = sizeof(username);
855 #else
856  uid_t user_id = geteuid();
857  char pwdbuf[BUFSIZ];
858  struct passwd pwdstr;
859  struct passwd *pw = NULL;
860  int pwerr;
861 #endif
862 
863  /*
864  * Some users are using configure --enable-thread-safety-force, so we
865  * might as well do the locking within our library to protect
866  * pqGetpwuid(). In fact, application developers can use getpwuid() in
867  * their application if they use the locking call we provide, or install
868  * their own locking function using PQregisterThreadLock().
869  */
870  pglock_thread();
871 
872 #ifdef WIN32
873  if (GetUserName(username, &namesize))
874  name = username;
875  else if (errorMessage)
876  printfPQExpBuffer(errorMessage,
877  libpq_gettext("user name lookup failure: error code %lu\n"),
878  GetLastError());
879 #else
880  pwerr = pqGetpwuid(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw);
881  if (pw != NULL)
882  name = pw->pw_name;
883  else if (errorMessage)
884  {
885  if (pwerr != 0)
886  printfPQExpBuffer(errorMessage,
887  libpq_gettext("could not look up local user ID %d: %s\n"),
888  (int) user_id,
889  pqStrerror(pwerr, pwdbuf, sizeof(pwdbuf)));
890  else
891  printfPQExpBuffer(errorMessage,
892  libpq_gettext("local user with ID %d does not exist\n"),
893  (int) user_id);
894  }
895 #endif
896 
897  if (name)
898  {
899  result = strdup(name);
900  if (result == NULL && errorMessage)
901  printfPQExpBuffer(errorMessage,
902  libpq_gettext("out of memory\n"));
903  }
904 
905  pgunlock_thread();
906 
907  return result;
908 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int uid_t
Definition: win32.h:260
char * pqStrerror(int errnum, char *strerrbuf, size_t buflen)
Definition: thread.c:61
#define pglock_thread()
Definition: libpq-int.h:571
return result
Definition: formatting.c:1618
static char * username
Definition: initdb.c:131
#define NULL
Definition: c.h:229
const char * name
Definition: encode.c:521
int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer, size_t buflen, struct passwd **result)
Definition: thread.c:95
#define pgunlock_thread()
Definition: libpq-int.h:572
#define libpq_gettext(x)
Definition: libpq-int.h:692
int pg_fe_sendauth ( AuthRequest  areq,
PGconn conn 
)

Definition at line 641 of file fe-auth.c.

References AUTH_REQ_CRYPT, AUTH_REQ_GSS, AUTH_REQ_GSS_CONT, pg_conn::auth_req_inbuf, AUTH_REQ_KRB4, AUTH_REQ_KRB5, AUTH_REQ_MD5, AUTH_REQ_OK, AUTH_REQ_PASSWORD, AUTH_REQ_SASL, AUTH_REQ_SASL_CONT, AUTH_REQ_SCM_CREDS, AUTH_REQ_SSPI, pg_conn::connhost, pg_conn::errorMessage, PQExpBufferData::len, libpq_gettext, NULL, password, pg_conn_host::password, pg_conn::password_needed, pg_local_sendauth(), pg_password_sendauth(), pg_SASL_exchange(), pg_SASL_init(), pg_strcasecmp(), pglock_thread, pg_conn::pgpass, pgunlock_thread, PQnoPasswordSupplied, printfPQExpBuffer(), pg_conn::sasl_state, STATUS_ERROR, STATUS_OK, and pg_conn::whichhost.

Referenced by PQconnectPoll().

642 {
643  switch (areq)
644  {
645  case AUTH_REQ_OK:
646  break;
647 
648  case AUTH_REQ_KRB4:
650  libpq_gettext("Kerberos 4 authentication not supported\n"));
651  return STATUS_ERROR;
652 
653  case AUTH_REQ_KRB5:
655  libpq_gettext("Kerberos 5 authentication not supported\n"));
656  return STATUS_ERROR;
657 
658 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
659  case AUTH_REQ_GSS:
660 #if !defined(ENABLE_SSPI)
661  /* no native SSPI, so use GSSAPI library for it */
662  case AUTH_REQ_SSPI:
663 #endif
664  {
665  int r;
666 
667  pglock_thread();
668 
669  /*
670  * If we have both GSS and SSPI support compiled in, use SSPI
671  * support by default. This is overridable by a connection
672  * string parameter. Note that when using SSPI we still leave
673  * the negotiate parameter off, since we want SSPI to use the
674  * GSSAPI kerberos protocol. For actual SSPI negotiate
675  * protocol, we use AUTH_REQ_SSPI.
676  */
677 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
678  if (conn->gsslib && (pg_strcasecmp(conn->gsslib, "gssapi") == 0))
679  r = pg_GSS_startup(conn);
680  else
681  r = pg_SSPI_startup(conn, 0);
682 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
683  r = pg_GSS_startup(conn);
684 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
685  r = pg_SSPI_startup(conn, 0);
686 #endif
687  if (r != STATUS_OK)
688  {
689  /* Error message already filled in. */
690  pgunlock_thread();
691  return STATUS_ERROR;
692  }
693  pgunlock_thread();
694  }
695  break;
696 
697  case AUTH_REQ_GSS_CONT:
698  {
699  int r;
700 
701  pglock_thread();
702 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
703  if (conn->usesspi)
704  r = pg_SSPI_continue(conn);
705  else
706  r = pg_GSS_continue(conn);
707 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
708  r = pg_GSS_continue(conn);
709 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
710  r = pg_SSPI_continue(conn);
711 #endif
712  if (r != STATUS_OK)
713  {
714  /* Error message already filled in. */
715  pgunlock_thread();
716  return STATUS_ERROR;
717  }
718  pgunlock_thread();
719  }
720  break;
721 #else /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
722  /* No GSSAPI *or* SSPI support */
723  case AUTH_REQ_GSS:
724  case AUTH_REQ_GSS_CONT:
726  libpq_gettext("GSSAPI authentication not supported\n"));
727  return STATUS_ERROR;
728 #endif /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
729 
730 #ifdef ENABLE_SSPI
731  case AUTH_REQ_SSPI:
732 
733  /*
734  * SSPI has it's own startup message so libpq can decide which
735  * method to use. Indicate to pg_SSPI_startup that we want SSPI
736  * negotiation instead of Kerberos.
737  */
738  pglock_thread();
739  if (pg_SSPI_startup(conn, 1) != STATUS_OK)
740  {
741  /* Error message already filled in. */
742  pgunlock_thread();
743  return STATUS_ERROR;
744  }
745  pgunlock_thread();
746  break;
747 #else
748 
749  /*
750  * No SSPI support. However, if we have GSSAPI but not SSPI
751  * support, AUTH_REQ_SSPI will have been handled in the codepath
752  * for AUTH_REQ_GSSAPI above, so don't duplicate the case label in
753  * that case.
754  */
755 #if !defined(ENABLE_GSS)
756  case AUTH_REQ_SSPI:
758  libpq_gettext("SSPI authentication not supported\n"));
759  return STATUS_ERROR;
760 #endif /* !define(ENABLE_GSSAPI) */
761 #endif /* ENABLE_SSPI */
762 
763 
764  case AUTH_REQ_CRYPT:
766  libpq_gettext("Crypt authentication not supported\n"));
767  return STATUS_ERROR;
768 
769  case AUTH_REQ_MD5:
770  case AUTH_REQ_PASSWORD:
771  {
772  char *password;
773 
774  conn->password_needed = true;
775  password = conn->connhost[conn->whichhost].password;
776  if (password == NULL)
777  password = conn->pgpass;
778  if (password == NULL || password[0] == '\0')
779  {
782  return STATUS_ERROR;
783  }
784  if (pg_password_sendauth(conn, password, areq) != STATUS_OK)
785  {
787  "fe_sendauth: error sending password authentication\n");
788  return STATUS_ERROR;
789  }
790  break;
791  }
792 
793  case AUTH_REQ_SASL:
794 
795  /*
796  * The request contains the name (as assigned by IANA) of the
797  * authentication mechanism.
798  */
799  if (pg_SASL_init(conn, conn->auth_req_inbuf) != STATUS_OK)
800  {
801  /* pg_SASL_init already set the error message */
802  return STATUS_ERROR;
803  }
804  /* fall through */
805 
806  case AUTH_REQ_SASL_CONT:
807  if (conn->sasl_state == NULL)
808  {
810  "fe_sendauth: invalid authentication request from server: AUTH_REQ_SASL_CONT without AUTH_REQ_SASL\n");
811  return STATUS_ERROR;
812  }
813  if (pg_SASL_exchange(conn) != STATUS_OK)
814  {
815  /* Use error message, if set already */
816  if (conn->errorMessage.len == 0)
818  "fe_sendauth: error in SASL authentication\n");
819  return STATUS_ERROR;
820  }
821  break;
822 
823  case AUTH_REQ_SCM_CREDS:
824  if (pg_local_sendauth(conn) != STATUS_OK)
825  return STATUS_ERROR;
826  break;
827 
828  default:
830  libpq_gettext("authentication method %u not supported\n"), areq);
831  return STATUS_ERROR;
832  }
833 
834  return STATUS_OK;
835 }
static char password[100]
Definition: streamutil.c:41
static bool pg_SASL_init(PGconn *conn, const char *auth_mechanism)
Definition: fe-auth.c:440
#define AUTH_REQ_SSPI
Definition: pqcomm.h:174
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static int pg_local_sendauth(PGconn *conn)
Definition: fe-auth.c:528
bool password_needed
Definition: libpq-int.h:408
#define AUTH_REQ_OK
Definition: pqcomm.h:165
#define AUTH_REQ_GSS
Definition: pqcomm.h:172
static int pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
Definition: fe-auth.c:580
#define STATUS_ERROR
Definition: c.h:976
#define pglock_thread()
Definition: libpq-int.h:571
#define PQnoPasswordSupplied
Definition: libpq-fe.h:512
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define AUTH_REQ_MD5
Definition: pqcomm.h:170
char * auth_req_inbuf
Definition: libpq-int.h:456
pg_conn_host * connhost
Definition: libpq-int.h:397
void * sasl_state
Definition: libpq-int.h:460
#define AUTH_REQ_CRYPT
Definition: pqcomm.h:169
#define STATUS_OK
Definition: c.h:975
#define AUTH_REQ_PASSWORD
Definition: pqcomm.h:168
PQExpBufferData errorMessage
Definition: libpq-int.h:501
#define AUTH_REQ_KRB5
Definition: pqcomm.h:167
#define AUTH_REQ_SASL_CONT
Definition: pqcomm.h:176
#define NULL
Definition: c.h:229
#define AUTH_REQ_KRB4
Definition: pqcomm.h:166
char * pgpass
Definition: libpq-int.h:343
#define AUTH_REQ_SASL
Definition: pqcomm.h:175
static int pg_SASL_exchange(PGconn *conn)
Definition: fe-auth.c:486
#define AUTH_REQ_GSS_CONT
Definition: pqcomm.h:173
#define pgunlock_thread()
Definition: libpq-int.h:572
int whichhost
Definition: libpq-int.h:396
#define libpq_gettext(x)
Definition: libpq-int.h:692
#define AUTH_REQ_SCM_CREDS
Definition: pqcomm.h:171
char * password
Definition: libpq-int.h:311
static int pg_local_sendauth ( PGconn conn)
static

Definition at line 528 of file fe-auth.c.

References buf, pg_conn::errorMessage, libpq_gettext, pqStrerror(), printfPQExpBuffer(), pg_conn::sock, STATUS_ERROR, and STATUS_OK.

Referenced by pg_fe_sendauth().

529 {
530 #ifdef HAVE_STRUCT_CMSGCRED
531  char buf;
532  struct iovec iov;
533  struct msghdr msg;
534  struct cmsghdr *cmsg;
535  union
536  {
537  struct cmsghdr hdr;
538  unsigned char buf[CMSG_SPACE(sizeof(struct cmsgcred))];
539  } cmsgbuf;
540 
541  /*
542  * The backend doesn't care what we send here, but it wants exactly one
543  * character to force recvmsg() to block and wait for us.
544  */
545  buf = '\0';
546  iov.iov_base = &buf;
547  iov.iov_len = 1;
548 
549  memset(&msg, 0, sizeof(msg));
550  msg.msg_iov = &iov;
551  msg.msg_iovlen = 1;
552 
553  /* We must set up a message that will be filled in by kernel */
554  memset(&cmsgbuf, 0, sizeof(cmsgbuf));
555  msg.msg_control = &cmsgbuf.buf;
556  msg.msg_controllen = sizeof(cmsgbuf.buf);
557  cmsg = CMSG_FIRSTHDR(&msg);
558  cmsg->cmsg_len = CMSG_LEN(sizeof(struct cmsgcred));
559  cmsg->cmsg_level = SOL_SOCKET;
560  cmsg->cmsg_type = SCM_CREDS;
561 
562  if (sendmsg(conn->sock, &msg, 0) == -1)
563  {
564  char sebuf[256];
565 
567  "pg_local_sendauth: sendmsg: %s\n",
568  pqStrerror(errno, sebuf, sizeof(sebuf)));
569  return STATUS_ERROR;
570  }
571  return STATUS_OK;
572 #else
574  libpq_gettext("SCM_CRED authentication method not supported\n"));
575  return STATUS_ERROR;
576 #endif
577 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * pqStrerror(int errnum, char *strerrbuf, size_t buflen)
Definition: thread.c:61
#define STATUS_ERROR
Definition: c.h:976
static char * buf
Definition: pg_test_fsync.c:65
#define STATUS_OK
Definition: c.h:975
pgsocket sock
Definition: libpq-int.h:400
PQExpBufferData errorMessage
Definition: libpq-int.h:501
#define libpq_gettext(x)
Definition: libpq-int.h:692
static int pg_password_sendauth ( PGconn conn,
const char *  password,
AuthRequest  areq 
)
static

Definition at line 580 of file fe-auth.c.

References AUTH_REQ_MD5, AUTH_REQ_PASSWORD, pg_conn::errorMessage, free, libpq_gettext, malloc, MD5_PASSWD_LEN, pg_conn::md5Salt, NULL, password, pg_md5_encrypt(), PG_PROTOCOL_MAJOR, pg_conn::pguser, pqPacketSend(), printfPQExpBuffer(), pg_conn::pversion, and STATUS_ERROR.

Referenced by pg_fe_sendauth().

581 {
582  int ret;
583  char *crypt_pwd = NULL;
584  const char *pwd_to_send;
585 
586  /* Encrypt the password if needed. */
587 
588  switch (areq)
589  {
590  case AUTH_REQ_MD5:
591  {
592  char *crypt_pwd2;
593 
594  /* Allocate enough space for two MD5 hashes */
595  crypt_pwd = malloc(2 * (MD5_PASSWD_LEN + 1));
596  if (!crypt_pwd)
597  {
599  libpq_gettext("out of memory\n"));
600  return STATUS_ERROR;
601  }
602 
603  crypt_pwd2 = crypt_pwd + MD5_PASSWD_LEN + 1;
604  if (!pg_md5_encrypt(password, conn->pguser,
605  strlen(conn->pguser), crypt_pwd2))
606  {
607  free(crypt_pwd);
608  return STATUS_ERROR;
609  }
610  if (!pg_md5_encrypt(crypt_pwd2 + strlen("md5"), conn->md5Salt,
611  sizeof(conn->md5Salt), crypt_pwd))
612  {
613  free(crypt_pwd);
614  return STATUS_ERROR;
615  }
616 
617  pwd_to_send = crypt_pwd;
618  break;
619  }
620  case AUTH_REQ_PASSWORD:
621  pwd_to_send = password;
622  break;
623  default:
624  return STATUS_ERROR;
625  }
626  /* Packet has a message type as of protocol 3.0 */
627  if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
628  ret = pqPacketSend(conn, 'p', pwd_to_send, strlen(pwd_to_send) + 1);
629  else
630  ret = pqPacketSend(conn, 0, pwd_to_send, strlen(pwd_to_send) + 1);
631  if (crypt_pwd)
632  free(crypt_pwd);
633  return ret;
634 }
static char password[100]
Definition: streamutil.c:41
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define STATUS_ERROR
Definition: c.h:976
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:104
#define AUTH_REQ_MD5
Definition: pqcomm.h:170
#define malloc(a)
Definition: header.h:50
bool pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf)
Definition: md5.c:323
char md5Salt[4]
Definition: libpq-int.h:422
char * pguser
Definition: libpq-int.h:342
#define AUTH_REQ_PASSWORD
Definition: pqcomm.h:168
PQExpBufferData errorMessage
Definition: libpq-int.h:501
#define MD5_PASSWD_LEN
Definition: md5.h:19
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
ProtocolVersion pversion
Definition: libpq-int.h:404
int pqPacketSend(PGconn *conn, char pack_type, const void *buf, size_t buf_len)
Definition: fe-connect.c:3913
#define libpq_gettext(x)
Definition: libpq-int.h:692
static int pg_SASL_exchange ( PGconn conn)
static

Definition at line 486 of file fe-auth.c.

References pg_conn::auth_req_inbuf, pg_conn::auth_req_inlen, pg_conn::errorMessage, free, output(), pg_fe_scram_exchange(), pqPacketSend(), pg_conn::sasl_state, STATUS_ERROR, STATUS_OK, and success.

Referenced by pg_fe_sendauth().

487 {
488  char *output;
489  int outputlen;
490  bool done;
491  bool success;
492  int res;
493 
495  conn->auth_req_inbuf, conn->auth_req_inlen,
496  &output, &outputlen,
497  &done, &success, &conn->errorMessage);
498  if (outputlen != 0)
499  {
500  /*
501  * Send the SASL response to the server. We don't care if it's the
502  * first or subsequent packet, just send the same kind of password
503  * packet.
504  */
505  res = pqPacketSend(conn, 'p', output, outputlen);
506  free(output);
507 
508  if (res != STATUS_OK)
509  return STATUS_ERROR;
510  }
511 
512  if (done && !success)
513  return STATUS_ERROR;
514 
515  return STATUS_OK;
516 }
static void output(uint64 loop_count)
#define STATUS_ERROR
Definition: c.h:976
void pg_fe_scram_exchange(void *opaq, char *input, int inputlen, char **output, int *outputlen, bool *done, bool *success, PQExpBuffer errorMessage)
char * auth_req_inbuf
Definition: libpq-int.h:456
int auth_req_inlen
Definition: libpq-int.h:457
static bool success
Definition: pg_basebackup.c:96
void * sasl_state
Definition: libpq-int.h:460
#define STATUS_OK
Definition: c.h:975
PQExpBufferData errorMessage
Definition: libpq-int.h:501
#define free(a)
Definition: header.h:65
int pqPacketSend(PGconn *conn, char pack_type, const void *buf, size_t buf_len)
Definition: fe-connect.c:3913
static bool pg_SASL_init ( PGconn conn,
const char *  auth_mechanism 
)
static

Definition at line 440 of file fe-auth.c.

References pg_conn::auth_req_inbuf, pg_conn::connhost, pg_conn::errorMessage, libpq_gettext, NULL, password, pg_conn_host::password, pg_conn::password_needed, pg_fe_scram_init(), pg_conn::pgpass, pg_conn::pguser, PQnoPasswordSupplied, printfPQExpBuffer(), pg_conn::sasl_state, SCRAM_SHA256_NAME, STATUS_ERROR, STATUS_OK, and pg_conn::whichhost.

Referenced by pg_fe_sendauth().

441 {
442  /*
443  * Check the authentication mechanism (only SCRAM-SHA-256 is supported at
444  * the moment.)
445  */
446  if (strcmp(auth_mechanism, SCRAM_SHA256_NAME) == 0)
447  {
448  char *password;
449 
450  conn->password_needed = true;
451  password = conn->connhost[conn->whichhost].password;
452  if (password == NULL)
453  password = conn->pgpass;
454  if (password == NULL || password[0] == '\0')
455  {
458  return STATUS_ERROR;
459  }
460 
461  conn->sasl_state = pg_fe_scram_init(conn->pguser, password);
462  if (!conn->sasl_state)
463  {
465  libpq_gettext("out of memory\n"));
466  return STATUS_ERROR;
467  }
468 
469  return STATUS_OK;
470  }
471  else
472  {
474  libpq_gettext("SASL authentication mechanism %s not supported\n"),
475  (char *) conn->auth_req_inbuf);
476  return STATUS_ERROR;
477  }
478 }
static char password[100]
Definition: streamutil.c:41
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
bool password_needed
Definition: libpq-int.h:408
#define STATUS_ERROR
Definition: c.h:976
#define PQnoPasswordSupplied
Definition: libpq-fe.h:512
char * auth_req_inbuf
Definition: libpq-int.h:456
pg_conn_host * connhost
Definition: libpq-int.h:397
void * sasl_state
Definition: libpq-int.h:460
#define SCRAM_SHA256_NAME
Definition: scram.h:17
#define STATUS_OK
Definition: c.h:975
char * pguser
Definition: libpq-int.h:342
void * pg_fe_scram_init(const char *username, const char *password)
Definition: fe-auth-scram.c:82
PQExpBufferData errorMessage
Definition: libpq-int.h:501
#define NULL
Definition: c.h:229
char * pgpass
Definition: libpq-int.h:343
int whichhost
Definition: libpq-int.h:396
#define libpq_gettext(x)
Definition: libpq-int.h:692
char * password
Definition: libpq-int.h:311
char* PQencryptPassword ( const char *  passwd,
const char *  user 
)

Definition at line 930 of file fe-auth.c.

References free, malloc, MD5_PASSWD_LEN, NULL, and pg_md5_encrypt().

Referenced by exec_command(), and main().

931 {
932  char *crypt_pwd;
933 
934  crypt_pwd = malloc(MD5_PASSWD_LEN + 1);
935  if (!crypt_pwd)
936  return NULL;
937 
938  if (!pg_md5_encrypt(passwd, user, strlen(user), crypt_pwd))
939  {
940  free(crypt_pwd);
941  return NULL;
942  }
943 
944  return crypt_pwd;
945 }
#define malloc(a)
Definition: header.h:50
bool pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf)
Definition: md5.c:323
#define MD5_PASSWD_LEN
Definition: md5.h:19
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
static char * user
Definition: pg_regress.c:92