📄 fe-auth.c
字号:
pg_krb5_authname(const char *PQerrormsg){ krb5_ccache ccache; krb5_principal principal; krb5_error_code code; static char *authname = (char *) NULL; if (authname) return authname; ccache = pg_krb5_init(); /* don't free this */ if (code = krb5_cc_get_principal(ccache, &principal)) { (void) sprintf(PQerrormsg, "pg_krb5_authname: Kerberos error %d in krb5_cc_get_principal\n", code); com_err("pg_krb5_authname", code, "in krb5_cc_get_principal"); return (char *) NULL; } if (code = krb5_unparse_name(principal, &authname)) { (void) sprintf(PQerrormsg, "pg_krb5_authname: Kerberos error %d in krb5_unparse_name\n", code); com_err("pg_krb5_authname", code, "in krb5_unparse_name"); krb5_free_principal(principal); return (char *) NULL; } krb5_free_principal(principal); return pg_an_to_ln(authname);}/* * pg_krb5_sendauth -- client routine to send authentication information to * the server * * This routine does not do mutual authentication, nor does it return enough * information to do encrypted connections. But then, if we want to do * encrypted connections, we'll have to redesign the whole RPC mechanism * anyway. * * Server hostnames are canonicalized v4-style, i.e., all domain suffixes * are simply chopped off. Hence, we are assuming that you've entered your * server instances as * <value-of-PG_KRB_SRVNAM>/<canonicalized-hostname> * in the PGREALM (or local) database. This is probably a bad assumption. */static intpg_krb5_sendauth(const char *PQerrormsg, int sock, struct sockaddr_in * laddr, struct sockaddr_in * raddr, const char *hostname){ char servbuf[MAXHOSTNAMELEN + 1 + sizeof(PG_KRB_SRVNAM)]; const char *hostp; const char *realm; krb5_error_code code; krb5_principal client, server; krb5_ccache ccache; krb5_error *error = (krb5_error *) NULL; ccache = pg_krb5_init(); /* don't free this */ /* * set up client -- this is easy, we can get it out of the ticket * file. */ if (code = krb5_cc_get_principal(ccache, &client)) { (void) sprintf(PQerrormsg, "pg_krb5_sendauth: Kerberos error %d in krb5_cc_get_principal\n", code); com_err("pg_krb5_sendauth", code, "in krb5_cc_get_principal"); return STATUS_ERROR; } /* * set up server -- canonicalize as described above */ strcpy(servbuf, PG_KRB_SRVNAM); *(hostp = servbuf + (sizeof(PG_KRB_SRVNAM) - 1)) = '/'; if (hostname || *hostname) strncpy(++hostp, hostname, MAXHOSTNAMELEN); else { if (gethostname(++hostp, MAXHOSTNAMELEN) < 0) strcpy(hostp, "localhost"); } if (hostp = strchr(hostp, '.')) *hostp = '\0'; if (realm = getenv("PGREALM")) { strcat(servbuf, "@"); strcat(servbuf, realm); } if (code = krb5_parse_name(servbuf, &server)) { (void) sprintf(PQerrormsg, "pg_krb5_sendauth: Kerberos error %d in krb5_parse_name\n", code); com_err("pg_krb5_sendauth", code, "in krb5_parse_name"); krb5_free_principal(client); return STATUS_ERROR; } /* * The only thing we want back from krb5_sendauth is an error status * and any error messages. */ if (code = krb5_sendauth((krb5_pointer) & sock, PG_KRB5_VERSION, client, server, (krb5_flags) 0, (krb5_checksum *) NULL, (krb5_creds *) NULL, ccache, (krb5_int32 *) NULL, (krb5_keyblock **) NULL, &error, (krb5_ap_rep_enc_part **) NULL)) { if ((code == KRB5_SENDAUTH_REJECTED) && error) { (void) sprintf(PQerrormsg, "pg_krb5_sendauth: authentication rejected: \"%*s\"\n", error->text.length, error->text.data); } else { (void) sprintf(PQerrormsg, "pg_krb5_sendauth: Kerberos error %d in krb5_sendauth\n", code); com_err("pg_krb5_sendauth", code, "in krb5_sendauth"); } } krb5_free_principal(client); krb5_free_principal(server); return code ? STATUS_ERROR : STATUS_OK;}#endif /* KRB5 */static intpg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq){ /* Encrypt the password if needed. */ if (areq == AUTH_REQ_CRYPT) password = crypt(password, conn->salt); return pqPacketSend(conn, password, strlen(password) + 1);}/* * fe_sendauth -- client demux routine for outgoing authentication information */intfe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname, const char *password, char *PQerrormsg){ switch (areq) { case AUTH_REQ_OK: break; case AUTH_REQ_KRB4:#ifdef KRB4 if (pg_krb4_sendauth(PQerrormsg, conn->sock, &conn->laddr.in, &conn->raddr.in, hostname) != STATUS_OK) { (void) sprintf(PQerrormsg, "fe_sendauth: krb4 authentication failed\n"); return STATUS_ERROR; } break;#else (void) sprintf(PQerrormsg, "fe_sendauth: krb4 authentication not supported\n"); return STATUS_ERROR;#endif case AUTH_REQ_KRB5:#ifdef KRB5 if (pg_krb5_sendauth(PQerrormsg, conn->sock, &conn->laddr.in, &conn->raddr.in, hostname) != STATUS_OK) { (void) sprintf(PQerrormsg, "fe_sendauth: krb5 authentication failed\n"); return STATUS_ERROR; } break;#else (void) sprintf(PQerrormsg, "fe_sendauth: krb5 authentication not supported\n"); return STATUS_ERROR;#endif case AUTH_REQ_PASSWORD: case AUTH_REQ_CRYPT: if (password == NULL || *password == '\0') { (void) sprintf(PQerrormsg, "fe_sendauth: no password supplied\n"); return STATUS_ERROR; } if (pg_password_sendauth(conn, password, areq) != STATUS_OK) { (void) sprintf(PQerrormsg, "fe_sendauth: error sending password authentication\n"); return STATUS_ERROR; } break; default: (void) sprintf(PQerrormsg, "fe_sendauth: authentication type %u not supported\n", areq); return STATUS_ERROR; } return STATUS_OK;}/* * fe_setauthsvc * fe_getauthsvc * * Set/return the authentication service currently selected for use by the * frontend. (You can only use one in the frontend, obviously.) */static int pg_authsvc = -1;voidfe_setauthsvc(const char *name, char *PQerrormsg){ int i; for (i = 0; i < n_authsvcs; ++i) if (!strcmp(name, authsvcs[i].name)) { pg_authsvc = i; break; } if (i == n_authsvcs) { (void) sprintf(PQerrormsg, "fe_setauthsvc: invalid name: %s, ignoring...\n", name); } return;}MsgTypefe_getauthsvc(char *PQerrormsg){ if (pg_authsvc < 0 || pg_authsvc >= n_authsvcs) fe_setauthsvc(DEFAULT_CLIENT_AUTHSVC, PQerrormsg); return authsvcs[pg_authsvc].msgtype;}/* * fe_getauthname -- returns a pointer to dynamic space containing whatever * name the user has authenticated to the system * if there is an error, return the error message in PQerrormsg */char *fe_getauthname(char *PQerrormsg){ char *name = (char *) NULL; char *authn = (char *) NULL; MsgType authsvc; authsvc = fe_getauthsvc(PQerrormsg); switch ((int) authsvc) {#ifdef KRB4 case STARTUP_KRB4_MSG: name = pg_krb4_authname(PQerrormsg); break;#endif#ifdef KRB5 case STARTUP_KRB5_MSG: name = pg_krb5_authname(PQerrormsg); break;#endif case STARTUP_MSG: {#ifdef WIN32 char username[128]; DWORD namesize = sizeof(username) - 1; if (GetUserName(username, &namesize)) name = username;#else struct passwd *pw = getpwuid(geteuid()); if (pw) name = pw->pw_name;#endif } break; default: (void) sprintf(PQerrormsg, "fe_getauthname: invalid authentication system: %d\n", authsvc); break; } if (name && (authn = (char *) malloc(strlen(name) + 1))) strcpy(authn, name); return authn;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -