--- Makefile Mon Nov 15 15:18:37 2004 +++ Makefile Mon Dec 13 10:43:02 2004 @@ -142,6 +142,18 @@ cvm-vmailmgr-udp.o: compile cvm-vmailmgr cvm-vmailmgr.o: compile cvm-vmailmgr.c module.h facts.h errors.h cvm-vmailmgr.h ./compile cvm-vmailmgr.c +cvm-anon: load cvm-anon.o command.a crypt.lib shadow.lib socket.lib s.lib + ./load cvm-anon command.a client.a `cat socket.lib` `cat s.lib` -lbg-net + +cvm-anon.o: compile cvm-anon.c + ./compile cvm-anon.c + +cvm-chain: load cvm-chain.o module.a crypt.lib shadow.lib socket.lib s.lib + ./load cvm-chain module.a client.a `cat socket.lib` `cat s.lib` -lbg-net + +cvm-chain.o: compile cvm-chain.c + ./compile cvm-chain.c + facts.o: compile facts.c facts.h ./compile facts.c @@ -185,8 +197,10 @@ makelib: ) >makelib chmod 755 makelib -module.a: makelib facts.o module_command.o module_local.o module_log.o module_main.o module_output.o module_request.o module_udp.o - ./makelib module.a facts.o module_command.o module_local.o module_log.o module_main.o module_output.o module_request.o module_udp.o +module.a: makelib facts.o module_command.o module_local.o module_log.o module_main.o module_output.o \ + module_request.o module_udp.o + ./makelib module.a facts.o module_command.o module_local.o module_log.o module_main.o module_output.o \ + module_request.o module_udp.o module_command.o: compile module_command.c module.h facts.h errors.h ./compile module_command.c @@ -222,7 +236,7 @@ mysql: cvm-mysql cvm-mysql-local cvm-mys pgsql: cvm-pgsql cvm-pgsql-local cvm-pgsql-udp -programs: cvm-vmailmgr-udp sql-query-test cvm-testclient cvm-checkpassword cvm-vmailmgr cvm-qmail cvm-pwfile cvm-unix cvm-vmailmgr-local cvm-benchclient +programs: cvm-vmailmgr-udp sql-query-test cvm-testclient cvm-checkpassword cvm-vmailmgr cvm-qmail cvm-pwfile cvm-unix cvm-vmailmgr-local cvm-benchclient cvm-anon cvm-chain qmail-domains.o: compile qmail-domains.c qmail.h ./compile qmail-domains.c --- README.sg1.patch Wed Dec 31 19:00:00 1969 +++ README.sg1.patch Mon Dec 13 10:43:02 2004 @@ -0,0 +1,33 @@ +* Adds a "clean" target to the Makefile + +* In order to allow a module to be both a module and a client, all + module-only functions are renamed to begin with "cvm_module_", and all + client-only functions are renamed to begin with "cvm_client_". The old + names are #define'd to the new ones in "module.h" and "client.h", for + compatiblity. + +* A new module, cvm-anon, is created. This module does anonymous + authentication. Any users whose names appear in CVM_ANON_USERS are + accepted without any password at all; if a username is followed by + an equal sign and another username, any user logging in as the first + username will be treated as if they had logged in anonymously to the + second username. If CVM_ANON_NEXT is set, the environment variable + CVM_ALREADYAUTH is set, the username is passed onto the module whose + name is there to retrieve the other information. This module must + recognize CVM_ALREADYAUTH as meaning that the user is already + authenticated (cvm-unix has been modified in this way; other modules + will need similar modifications to be used in this way), and should + not have their password checked again. If CVM_ANON_NEXT isn't set, + the user's information is taken from the environment variables + CVM_ANON_USER, CVM_ANON_SHELL, CVM_ANON_UID, and CVM_ANON_GID. + +* A new module, cvm-chain, is created. This module runs a sequence of + CVM modules until one succeeds. It gets the list of modules to try + from the CVM_CHAIN environment variable, which should contain a + space-seperated list of modules to try, in the order they should be + tried. + +* The cvm-unix module is modified to recognize the environment + variable CVM_ALREADYAUTH as indicating that the user has already + authenticated some other way, and should just have their settings + retrieved. --- TARGETS Mon Nov 15 15:18:37 2004 +++ TARGETS Mon Dec 13 10:43:02 2004 @@ -20,6 +20,10 @@ cvm-mysql-local.o cvm-mysql-udp cvm-mysql-udp.o cvm-mysql.o +cvm-anon +cvm-anon.o +cvm-chain +cvm-chain.o cvm-pgsql cvm-pgsql-local cvm-pgsql-local.o --- client.h Mon Nov 15 15:18:37 2004 +++ client.h Mon Dec 13 10:43:02 2004 @@ -6,15 +6,32 @@ #define CVM_PROTOCOL 1 -extern const char* cvm_account_split_chars; -extern const char* cvm_ucspi_domain(void); -extern int cvm_authenticate(const char* module, const char* account, +extern const char* cvm_client_account_split_chars; +extern const char* cvm_client_ucspi_domain(void); +extern int cvm_client_authenticate(const char* module, const char* account, const char* domain, const char** credentials, int parse_account); -extern int cvm_fact_str(int number, const char** data); -extern int cvm_fact_uint(int number, unsigned long* data); +extern int cvm_client_fact_str(int number, const char** data); +extern int cvm_client_fact_uint(int number, unsigned long* data); -extern int cvm_setugid(void); -extern int cvm_setenv(void); +extern int cvm_client_setugid(void); +extern int cvm_client_setenv(void); + +/* legacy */ +#define cvm_account_split_chars cvm_client_account_split_chars +#define cvm_ucspi_domain cvm_client_ucspi_domain +#define cvm_setugid cvm_client_setugid +#define cvm_setenv cvm_client_setenv + +/* can't be duplicated */ +#ifndef CVM__MODULE__H__ +# define cvm_authenticate cvm_client_authenticate +# define cvm_fact_str cvm_client_fact_str +# define cvm_fact_uint cvm_client_fact_uint +#else +# undef cvm_authenticate +# undef cvm_fact_str +# undef cvm_fact_uint +#endif #endif --- cvm-anon.c Wed Dec 31 19:00:00 1969 +++ cvm-anon.c Mon Dec 13 10:43:02 2004 @@ -0,0 +1,154 @@ + +#include +#include +#include +#include + +#include + +#include "module.h" +#include "client.h" + +const char cvm_module_program[] = "cvm-anon"; + +const unsigned cvm_module_credential_count = 1; +const char *cvm_module_credentials[1]; + + +struct user_map { + char *user; + char *mapto; +}; + +struct user_map *anon_users; +struct user_map *um = 0; +int num_map, max_map; +#define ALLOC_COUNT 10 + + +char *next_cvm; +char *default_username, *default_home, *default_shell; +uid_t default_uid; +gid_t default_gid; + +int cvm_module_auth_init(void) +{ + char *e; + char *ws, *we, *eq; + char *user, *mapto; + + num_map = max_map = 0; + anon_users = NULL; + + if (!(next_cvm = getenv("CVM_ANON_NEXT"))) { + default_username = getenv("CVM_ANON_USER"); + + if (!(default_home = getenv("CVM_ANON_HOME"))) + return CVME_CONFIG; + if (!(default_shell = getenv("CVM_ANON_SHELL"))) + return CVME_CONFIG; + + if (!(e=getenv("CVM_ANON_UID"))) + return CVME_CONFIG; + if (!(default_uid=atoi(e))) + return CVME_CONFIG; + + if (!(e=getenv("CVM_ANON_GID"))) + return CVME_CONFIG; + if (!(default_gid=atoi(e))) + return CVME_CONFIG; + } + if (!(e=getenv("CVM_ANON_USERS"))) + return CVME_CONFIG; + + we = e; + while (1) { + ws = we; + eq = NULL; + while (*ws && (isspace(*ws) || !isprint(*ws))) { + ws++; + } + if (!*ws) + break; + we = ws; + + while (isprint(*we) && !isspace(*we)) { + if (*we == '=') + eq = we; + we++; + } + if (eq) { + if (!(user = malloc(eq-ws+1))) + return CVME_GENERAL; + memcpy(user,ws,eq-ws); + user[eq-ws]='\0'; + if (!(mapto = malloc(we-eq))) + return CVME_GENERAL; + memcpy(mapto,eq+1,we-eq-1); + mapto[we-eq-1]='\0'; + } + else { + if (!(user = malloc(we-ws+1))) + return CVME_GENERAL; + memcpy(user,ws,we-ws); + user[we-ws]='\0'; + mapto = user; + } + if (num_map >= max_map) { + max_map += ALLOC_COUNT; + if (!(anon_users = realloc(anon_users,max_map * sizeof(struct user_map)))) + return CVME_GENERAL; + } + anon_users[num_map].user = user; + anon_users[num_map].mapto = mapto; + num_map++; + } + return 0; +} + +int cvm_module_lookup(void) +{ + int i; + int r; + char *tmpstr; + long tmpl; + + for(i=0;i= num_map) + return CVME_PERMFAIL; +} + +int cvm_module_authenticate(void) +{ + return 0; +} + +int cvm_module_results(void) +{ + char *cred[] = { "", NULL }; + + if (next_cvm) { + if (putenv("CVM_ALREADYAUTH=cvm_anon") != 0) + return CVME_GENERAL; + + return cvm_client_authenticate(next_cvm, um->mapto, NULL, (const char **)cred, 0); + } + else { + cvm_fact_username = um->mapto; + if (default_username) + cvm_fact_username = default_username; + cvm_fact_userid = default_uid; + cvm_fact_groupid = default_gid; + cvm_fact_directory = default_home; + cvm_fact_shell = default_shell; + return 0; + } +} + +void cvm_module_auth_stop(void) +{ +} --- cvm-chain.c Wed Dec 31 19:00:00 1969 +++ cvm-chain.c Mon Dec 13 10:43:02 2004 @@ -0,0 +1,111 @@ +#include +#include +#include +#include + +#include + +#include "module.h" +#include "client.h" + +const char cvm_module_program[] = "cvm-chain"; + +const unsigned cvm_module_credential_count = 1; +const char *cvm_module_credentials[1]; + +char **chain; +int num_chain, max_chain; +#define ALLOC_COUNT 10 + +static void cvm_chain_init() +{ + cvm_fact_username = 0; + cvm_fact_userid = -1; + cvm_fact_groupid = -1; + cvm_fact_directory = 0; + cvm_fact_shell = 0; + cvm_fact_realname = 0; + cvm_fact_groupname = 0; + cvm_fact_sys_username = 0; + cvm_fact_sys_directory = 0; + cvm_fact_domain = 0; + cvm_fact_mailbox = 0; +} + +int cvm_module_auth_init(void) +{ + char *e; + char *ws, *we; + char *s; + + num_chain = max_chain = 0; + chain = NULL; + + if (!(e=getenv("CVM_CHAIN"))) + return CVME_CONFIG; + + we = e; + while (1) { + ws = we; + while (*ws && (isspace(*ws) || !isprint(*ws))) { + ws++; + } + if (!*ws) + break; + we = ws; + + while (isprint(*we) && !isspace(*we)) { + we++; + } + if (!(s = malloc(we-ws+1))) + return CVME_GENERAL; + memcpy(s,ws,we-ws); + s[we-ws]='\0'; + if (num_chain >= max_chain) { + max_chain += ALLOC_COUNT; + if (!(chain = realloc(chain,max_chain * sizeof(char *)))) + return CVME_GENERAL; + } + chain[num_chain] = s; + num_chain++; + } + cvm_chain_init(); + return 0; +} + +int cvm_module_lookup(void) +{ + return 0; +} + +int cvm_module_authenticate(void) +{ + int i; + int r; + char *tmp_fact_username; + char *tmp_fact_dir; + long tmpl_fact_uid; + long tmpl_fact_gid; + const char *cred[2]; + + cred[0]=cvm_module_credentials[0]; + cred[1]=NULL; + r=CVME_CONFIG; + for(i=0;i +#include #include #include #include #include -#include #include @@ -47,14 +47,18 @@ int cvm_lookup(void) { int err; if ((err = cvm_getpwnam(cvm_account_name, &pw)) != 0) return err; - if (pw->pw_passwd == 0) return CVME_PERMFAIL; + if (!getenv("CVM_ALREADYAUTH")) { + if (pw->pw_passwd == 0) return CVME_PERMFAIL; + } return 0; } int cvm_authenticate(void) { - if (strcmp(crypt(cvm_credentials[0], pw->pw_passwd), pw->pw_passwd) != 0) - return CVME_PERMFAIL; + if (!getenv("CVM_ALREADYAUTH")) { + if (strcmp(crypt(cvm_credentials[0], pw->pw_passwd), pw->pw_passwd) != 0) + return CVME_PERMFAIL; + } return 0; } @@ -76,7 +80,7 @@ int cvm_results(void) cvm_fact_groupname = 0; setgrent(); while ((gr = getgrent()) != 0) { - if (gr->gr_gid == pw->pw_gid) + if ((gid_t)gr->gr_gid == pw->pw_gid) cvm_fact_groupname = strdup(gr->gr_name); else { unsigned i; --- insthier.c Mon Nov 15 15:18:37 2004 +++ insthier.c Mon Dec 13 10:43:02 2004 @@ -31,6 +31,8 @@ void insthier(void) { c(dir, "cvm-vmailmgr-local", -1, -1, 0755); c(dir, "cvm-vmailmgr-udp", -1, -1, 0755); c(dir, "cvm-unix", -1, -1, 0755); + c(dir, "cvm-anon", -1, -1, 0755); + c(dir, "cvm-chain", -1, -1, 0755); dir = d(home, "include", -1, -1, 0755); s(dir, "cvm-sasl.h", "cvm/sasl.h"); --- module.h Mon Nov 15 15:18:37 2004 +++ module.h Mon Dec 13 10:43:02 2004 @@ -1,6 +1,8 @@ #ifndef CVM__MODULE__H__ #define CVM__MODULE__H__ +#include + #include "facts.h" #include "errors.h" @@ -12,39 +14,82 @@ #define CVM_PROTOCOL 1 -extern const char program[]; +extern const char cvm_module_program[]; -extern const char* cvm_account_name; -extern const char* cvm_account_domain; -extern const char* cvm_lookup_secret; +extern const char* cvm_module_account_name; +extern const char* cvm_module_account_domain; +extern const char* cvm_module_lookup_secret; -extern char outbuffer[BUFSIZE]; -extern unsigned outbuflen; -extern char inbuffer[BUFSIZE+1]; -extern unsigned inbuflen; +extern char cvm_module_outbuffer[BUFSIZE]; +extern unsigned cvm_module_outbuflen; +extern char cvm_module_inbuffer[BUFSIZE+1]; +extern unsigned cvm_module_inbuflen; -extern void cvm_fact_start(void); -extern int cvm_fact_str(int number, const char* data); -extern int cvm_fact_uint(int number, unsigned long data); -extern void cvm_fact_end(int code); +extern void cvm_module_fact_start(void); +extern int cvm_module_fact_str(int number, const char* data); +extern int cvm_module_fact_uint(int number, unsigned long data); +extern void cvm_module_fact_end(int code); -extern void init_request(void); -extern int handle_request(void); +extern void cvm_module_init_request(void); +extern int cvm_module_handle_request(void); -extern void log_startup(void); -extern void log_request(void); -extern void log_shutdown(void); +extern void cvm_module_log_startup(void); +extern void cvm_module_log_request(void); +extern void cvm_module_log_shutdown(void); -extern int cvm_parse_domain(const char* seperators); +extern int cvm_module_parse_domain(const char* seperators); /* The following need to be provided by the module. * The "credentials" global is filled by the input handling code. */ -extern const unsigned cvm_credential_count; -extern const char* cvm_credentials[]; -extern int cvm_auth_init(void); -extern int cvm_lookup(void); -extern int cvm_authenticate(void); -extern int cvm_results(void); -extern void cvm_auth_stop(void); +extern const unsigned cvm_module_credential_count; +extern const char* cvm_module_credentials[]; +extern int cvm_module_auth_init(void); +extern int cvm_module_lookup(void); +extern int cvm_module_authenticate(void); +extern int cvm_module_results(void); +extern void cvm_module_auth_stop(void); + + +/* legacy */ +#define program cvm_module_program + +#define cvm_account_name cvm_module_account_name +#define cvm_account_domain cvm_module_account_domain +#define cvm_lookup_secret cvm_module_lookup_secret + +#define outbuffer cvm_module_outbuffer +#define outbuflen cvm_module_outbuflen +#define inbuffer cvm_module_inbuffer +#define inbuflen cvm_module_inbuflen + +#define cvm_fact_start cvm_module_fact_start +#define cvm_fact_end cvm_module_fact_end + +#define init_request cvm_module_init_request +#define handle_request cvm_module_handle_request + +#define log_startup cvm_module_log_startup +#define log_request cvm_module_log_request +#define log_shutdown cvm_module_log_shutdown + +#define cvm_parse_domain cvm_module_parse_domain + +#define cvm_credential_count cvm_module_credential_count +#define cvm_credentials cvm_module_credentials +#define cvm_auth_init cvm_module_auth_init +#define cvm_lookup cvm_module_lookup +#define cvm_results cvm_module_results +#define cvm_auth_stop cvm_module_auth_stop + +/* can't be duplicated */ +#ifndef CVM__CLIENT__H__ +# define cvm_authenticate cvm_module_authenticate +# define cvm_fact_str cvm_module_fact_str +# define cvm_fact_uint cvm_module_fact_uint +#else +# undef cvm_authenticate +# undef cvm_fact_str +# undef cvm_fact_uint +#endif #endif --- sql-query-test.c Mon Nov 15 15:18:37 2004 +++ sql-query-test.c Mon Dec 13 10:43:02 2004 @@ -1,8 +1,8 @@ #include #include "sql.h" -const char* cvm_account_name; -const char* cvm_account_domain; +const char* cvm_module_account_name; +const char* cvm_module_account_domain; int main(int argc, char* argv[]) { @@ -15,8 +15,8 @@ int main(int argc, char* argv[]) puts("sql-query-test: validation of query failed"); return 2; } - cvm_account_name = argv[2]; - cvm_account_domain = argv[3]; + cvm_module_account_name = argv[2]; + cvm_module_account_domain = argv[3]; if (!sql_query_build(argv[1], &s)) { puts("sql-query-test: query building failed"); return 3;