From e828947d62af3796377d5d0f2543a07942279276 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ale=C5=A1=20K=C5=99enek?= Date: Thu, 7 Oct 2004 14:41:22 +0000 Subject: [PATCH] Pullup of INFN CVS changes -- mainly notifications --- org.glite.lb.server/src/bkserverd.c | 7 +- org.glite.lb.server/src/il_notification.c | 3 +- org.glite.lb.server/src/il_notification.h | 1 + org.glite.lb.server/src/lb_proto.c | 6 + org.glite.lb.server/src/lbs_db.c | 5 +- org.glite.lb.server/src/notification.c | 376 ++++++++++++++++++++++-------- 6 files changed, 303 insertions(+), 95 deletions(-) diff --git a/org.glite.lb.server/src/bkserverd.c b/org.glite.lb.server/src/bkserverd.c index 0c7efd1..d20403b 100644 --- a/org.glite.lb.server/src/bkserverd.c +++ b/org.glite.lb.server/src/bkserverd.c @@ -148,6 +148,7 @@ static struct option opts[] = { {"limits", 1, NULL, 'L'}, {"notif-dur", 1, NULL, 'N'}, {"notif-il-sock", 1, NULL, 'X'}, + {"notif-il-fprefix", 1, NULL, 'Y'}, {NULL,0,NULL,0} }; @@ -177,6 +178,7 @@ static void usage(char *me) "\t =2\t don't enforce indices at all\n" "\t--strict-locking=1\t lock jobs also on storing events (may be slow)\n" "\t--notif-il-sock\t socket to send notifications\n" + "\t--notif-il-fprefix\t file prefix for notifications\n" ,me); } @@ -504,7 +506,7 @@ int main(int argc,char *argv[]) if (geteuid()) snprintf(pidfile,sizeof pidfile,"%s/edg-bkserverd.pid", getenv("HOME")); - while ((opt = getopt_long(argc,argv,"a:c:k:C:V:p:drm:ns:l:L:N:i:S:D:X:",opts,NULL)) != EOF) switch (opt) { + while ((opt = getopt_long(argc,argv,"a:c:k:C:V:p:drm:ns:l:L:N:i:S:D:X:Y:",opts,NULL)) != EOF) switch (opt) { case 'a': fake_host = strdup(optarg); break; case 'c': cert = optarg; break; case 'k': key = optarg; break; @@ -528,6 +530,7 @@ int main(int argc,char *argv[]) break; case 'N': notif_duration = atoi(optarg) * (60*60); break; case 'X': notif_ilog_socket_path = strdup(optarg); break; + case 'Y': notif_ilog_file_prefix = strdup(optarg); break; case 'i': strcpy(pidfile,optarg); break; case 'R': if (super_users) { fprintf(stderr,"%s: super-users already defined, second occurence ignored\n", @@ -662,6 +665,7 @@ int main(int argc,char *argv[]) if (!cert || !key) fprintf(stderr,"%s: key or certificate file not specified - unable to watch them for changes!\n",argv[0]); if (cadir) setenv("X509_CERT_DIR",cadir,1); + edg_wll_gss_watch_creds(cert,&cert_mtime); if (edg_wll_gss_acquire_cred_gsi(cert, &mycred, &mysubj, &gss_code)) { dprintf(("Running unauthenticated\n")); } else { @@ -1125,6 +1129,7 @@ static int slave(void *mycred,int sock) ctx->p_tmp_timeout.tv_sec = SLAVE_TIMEOUT; ctx->poolSize = 1; + free(ctx->connPool); ctx->connPool = calloc(1,sizeof(edg_wll_ConnPool)); ctx->connToUse = 0; diff --git a/org.glite.lb.server/src/il_notification.c b/org.glite.lb.server/src/il_notification.c index 5ac8c53..0744d13 100644 --- a/org.glite.lb.server/src/il_notification.c +++ b/org.glite.lb.server/src/il_notification.c @@ -31,6 +31,7 @@ #define DEFAULT_SOCKET "/tmp/notif_interlogger.sock" char *notif_ilog_socket_path = DEFAULT_SOCKET; +char *notif_ilog_file_prefix = FILE_PREFIX; #define tv_sub(a,b) {\ (a).tv_usec -= (b).tv_usec;\ @@ -312,7 +313,7 @@ edg_wll_NotifSend(edg_wll_Context context, goto out; } - asprintf(&event_file, "%s.%s", FILE_PREFIX, reg_id_s); + asprintf(&event_file, "%s.%s", notif_ilog_file_prefix, reg_id_s); if(event_file == NULL) { edg_wll_SetError(context, ret=ENOMEM, "asprintf()"); goto out; diff --git a/org.glite.lb.server/src/il_notification.h b/org.glite.lb.server/src/il_notification.h index 3c842c9..f76a829 100644 --- a/org.glite.lb.server/src/il_notification.h +++ b/org.glite.lb.server/src/il_notification.h @@ -13,6 +13,7 @@ #endif extern char *notif_ilog_socket_path; +extern char *notif_ilog_file_prefix; /** Send ULM notification string to interlogger. * Stores notification to file according to registration id and send it diff --git a/org.glite.lb.server/src/lb_proto.c b/org.glite.lb.server/src/lb_proto.c index 4ab0453..582c41b 100644 --- a/org.glite.lb.server/src/lb_proto.c +++ b/org.glite.lb.server/src/lb_proto.c @@ -633,6 +633,8 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx, else if (!strncmp(requestPTR,KEY_PURGE_REQUEST,sizeof(KEY_PURGE_REQUEST)-1)) { edg_wll_PurgeRequest request; + ctx->p_tmp_timeout.tv_sec = 86400; + if ( !parsePurgeRequest(ctx,messageBody,(int (*)()) edg_wll_StringToStat,&request) ) edg_wll_PurgeServer(ctx, (const edg_wll_PurgeRequest *)&request); @@ -656,6 +658,8 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx, edg_wll_DumpRequest request; edg_wll_DumpResult result; + ctx->p_tmp_timeout.tv_sec = 86400; + memset(&request,0,sizeof(request)); memset(&result,0,sizeof(result)); @@ -686,6 +690,8 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx, edg_wll_LoadRequest request; edg_wll_LoadResult result; + ctx->p_tmp_timeout.tv_sec = 86400; + memset(&request,0,sizeof(request)); memset(&result,0,sizeof(result)); diff --git a/org.glite.lb.server/src/lbs_db.c b/org.glite.lb.server/src/lbs_db.c index ebe6362..16df6c9 100644 --- a/org.glite.lb.server/src/lbs_db.c +++ b/org.glite.lb.server/src/lbs_db.c @@ -53,7 +53,10 @@ edg_wll_ErrorCode edg_wll_DBConnect(edg_wll_Context ctx,char *cs) pw = slash+1; db = colon+1; - if (!mysql_real_connect((MYSQL *) ctx->mysql,host,user,pw,db,0,NULL,0)) { + /* ljocha: CLIENT_FOUND_ROWS added to make authorization check + * working in update_notif(). + * Hope it does not break anything else */ + if (!mysql_real_connect((MYSQL *) ctx->mysql,host,user,pw,db,0,NULL,CLIENT_FOUND_ROWS)) { free(buf); return my_err(); } diff --git a/org.glite.lb.server/src/notification.c b/org.glite.lb.server/src/notification.c index 048176e..5c88757 100644 --- a/org.glite.lb.server/src/notification.c +++ b/org.glite.lb.server/src/notification.c @@ -11,9 +11,13 @@ #include "lbs_db.h" -static char *get_user(edg_wll_Context ctx, int create); -static int update_notif(edg_wll_Context, const edg_wll_NotifId, - const char *, const char *, const char *); +static char *get_user(edg_wll_Context ctx, int create); +static int check_notif_request(edg_wll_Context, const edg_wll_NotifId, char **); +static int split_cond_list(edg_wll_Context, edg_wll_QueryRec const * const *, + edg_wll_QueryRec ***, char ***); +static int update_notif(edg_wll_Context, const edg_wll_NotifId, + const char *, const char *, const char *); + int edg_wll_NotifNewServer( edg_wll_Context ctx, @@ -22,9 +26,7 @@ int edg_wll_NotifNewServer( const edg_wll_NotifId nid, time_t *valid) { - int i, j, - ct, - new_rows; + int i; char *q = NULL, *nid_s = NULL, *time_s = NULL, @@ -46,47 +48,15 @@ int edg_wll_NotifNewServer( goto cleanup; /* Format conditions - * - first of all separate all jobids - * - then format new condition list without jobids and encode it into an XML string + * - separate all jobids + * - format new condition list without jobids */ - if ( !conditions || !conditions[0] ) - { - edg_wll_SetError(ctx, EINVAL, "Empty condition list"); + if ( split_cond_list(ctx, conditions, &nconds, &jobs) ) goto cleanup; - } - for ( new_rows = ct = i = 0; conditions[i]; i++ ) - { - if ( conditions[i][0].attr && conditions[i][0].attr != EDG_WLL_QUERY_ATTR_JOBID ) - new_rows++; - for ( j = 0; conditions[i][j].attr; j++ ) - if ( conditions[i][j].attr == EDG_WLL_QUERY_ATTR_JOBID ) - ct++; - } - if ( !ct ) - { - edg_wll_SetError(ctx, EINVAL, "Notification has to bind to at least one jobID"); - goto cleanup; - } - if ( !(jobs = calloc(ct+1, sizeof(char *))) - || !(nconds = calloc(new_rows+1, sizeof(edg_wll_QueryRec *))) ) - { - edg_wll_SetError(ctx, errno, NULL); - goto cleanup; - } - for ( ct = i = 0; conditions[i]; i++ ) - for ( j = 0; conditions[i][j].attr; j++ ) - if ( conditions[i][j].attr == EDG_WLL_QUERY_ATTR_JOBID ) - if ( !(jobs[ct++] = edg_wlc_JobIdGetUnique(conditions[i][j].value.j)) ) - { - edg_wll_SetError(ctx, errno, NULL); - goto cleanup; - } - for ( new_rows = i = 0; conditions[i]; i++ ) - if ( conditions[i][0].attr && conditions[i][0].attr != EDG_WLL_QUERY_ATTR_JOBID ) - /* !!! DO NOT DEALLOCATE this arrays (it is not neccessary to allocate new - * mem - it's used only once and only for xml parsing - */ - nconds[new_rows++] = (edg_wll_QueryRec *) (conditions[i]); + + /* + * encode new cond. list into a XML string + */ if ( edg_wll_JobQueryRecToXML(ctx, (edg_wll_QueryRec const * const *) nconds, &xml_conds) ) { /* XXX: edg_wll_JobQueryRecToXML() do not set errors in context! @@ -184,7 +154,8 @@ int edg_wll_NotifBindServer( const char *address_override, time_t *valid) { - char *time_s = NULL; + char *time_s = NULL, + *addr_s = NULL; if ( !address_override ) @@ -193,6 +164,9 @@ int edg_wll_NotifBindServer( goto cleanup; } + if ( check_notif_request(ctx, nid, NULL) ) + goto cleanup; + /* Format time of validity */ *valid = time(NULL); @@ -209,21 +183,133 @@ int edg_wll_NotifBindServer( } time_s[strlen(time_s)-1] = 0; - update_notif(ctx, nid, NULL, address_override, (const char *)(time_s+1)); + /* Format the address + */ + if ( address_override ) + { + char *aux; + + if ( !(aux = strchr(address_override, ':')) ) + { + edg_wll_SetError(ctx, EINVAL, "Addres overrirde not in format host:port"); + goto cleanup; + } + if ( !strncmp(address_override, "0.0.0.0", aux-address_override) ) + trio_asprintf(&addr_s, "%s:%s", ctx->connPool[ctx->connToUse].peerName, aux+1); + } + + + update_notif(ctx, nid, NULL, addr_s? addr_s: address_override, (const char *)(time_s+1)); cleanup: if ( time_s ) free(time_s); + if ( addr_s ) free(addr_s); return edg_wll_Error(ctx, NULL, NULL); } + int edg_wll_NotifChangeServer( edg_wll_Context ctx, - const edg_wll_NotifId id, + const edg_wll_NotifId nid, edg_wll_QueryRec const * const *conditions, edg_wll_NotifChangeOp op) { - return edg_wll_SetError(ctx, EINVAL, "Not yet implemented"); + int i; + char *q = NULL, + *nid_s = NULL, + *xml_conds = NULL, + **jobs = NULL; + edg_wll_QueryRec **nconds = NULL; + + + /* Format notification ID + */ + if ( !(nid_s = edg_wll_NotifIdGetUnique(nid)) ) + goto cleanup; + + if ( check_notif_request(ctx, nid, NULL) ) + goto cleanup; + + switch ( op ) + { + case EDG_WLL_NOTIF_REPLACE: + /* Format conditions + * - separate all jobids + * - format new condition list without jobids + */ + if ( split_cond_list(ctx, conditions, &nconds, &jobs) ) + goto cleanup; + + /* + * encode new cond. list into a XML string + */ + if ( edg_wll_JobQueryRecToXML(ctx, (edg_wll_QueryRec const * const *) nconds, &xml_conds) ) + { + /* XXX: edg_wll_JobQueryRecToXML() do not set errors in context! + * can't get propper error number :( + */ + edg_wll_SetError(ctx, errno, "Can't encode data into xml"); + goto cleanup; + } + + /* Format DB insert statement + */ + if ( update_notif(ctx, nid, xml_conds, NULL, NULL) ) + goto cleanup; + + if ( jobs ) + { + /* Format DB insert statement + */ + trio_asprintf(&q, "delete from notif_jobs where notifid='%|Ss'", nid_s); + if ( edg_wll_ExecStmt(ctx, q, NULL) < 0 ) + goto cleanup; + + for ( i = 0; jobs[i]; i++ ) + { + free(q); + trio_asprintf(&q, + "insert into notif_jobs(notifid,jobid) values ('%|Ss','%|Ss')", + nid_s, jobs[i]); + if ( edg_wll_ExecStmt(ctx, q, NULL) < 0 ) + { + /* XXX: Remove uncoplete registration? + * Which error has to be returned? + */ + free(q); + trio_asprintf(&q, "delete from notif_jobs where notifid='%|Ss'", nid_s); + edg_wll_ExecStmt(ctx, q, NULL); + free(q); + trio_asprintf(&q,"delete from notif_registrations where notifid='%|Ss'", nid_s); + edg_wll_ExecStmt(ctx, q, NULL); + goto cleanup; + } + } + } + break; + + case EDG_WLL_NOTIF_ADD: + break; + case EDG_WLL_NOTIF_REMOVE: + break; + default: + break; + } + +cleanup: + if ( q ) free(q); + if ( xml_conds ) free(xml_conds); + if ( nid_s ) free(nid_s); + if ( jobs ) + { + for ( i = 0; jobs[i]; i++ ) + free(jobs[i]); + free(jobs); + } + if ( nconds ) free(nconds); + + return edg_wll_Error(ctx, NULL, NULL); } int edg_wll_NotifRefreshServer( @@ -234,6 +320,9 @@ int edg_wll_NotifRefreshServer( char *time_s = NULL; + if ( check_notif_request(ctx, nid, NULL) ) + goto cleanup; + /* Format time of validity */ *valid = time(NULL); @@ -262,54 +351,32 @@ int edg_wll_NotifDropServer( edg_wll_Context ctx, edg_wll_NotifId *nid) { - char *owner = NULL, - *nid_s = NULL, + char *nid_s = NULL, *stmt; int ret; - if ( !(owner = get_user(ctx, 0)) ) - { - if ( !edg_wll_Error(ctx, NULL, NULL) ) - edg_wll_SetError(ctx, EPERM, "Unknown user"); - - return edg_wll_Error(ctx, NULL, NULL); - } + if ( check_notif_request(ctx, nid, NULL) ) + goto cleanup; if ( !(nid_s = edg_wll_NotifIdGetUnique(nid)) ) goto cleanup; - /* Only the owner could remove the notification registration - */ - trio_asprintf(&stmt, - "delete from notif_registrations where notifid='%|Ss' and userid='%|Ss'", - nid_s, owner); + trio_asprintf(&stmt, "delete from notif_registrations where notifid='%|Ss'", nid_s); if ( (ret = edg_wll_ExecStmt(ctx, stmt, NULL)) < 0 ) goto cleanup; free(stmt); - if ( ret == 0 ) - { - trio_asprintf(&stmt, - "select notifid from notif_registrations where notifid='%|Ss'", nid_s); - ret = edg_wll_ExecStmt(ctx, stmt, NULL); - if ( ret == 0 ) - edg_wll_SetError(ctx, ENOENT, "Unknown notification ID"); - else if ( ret > 0 ) - edg_wll_SetError(ctx, EPERM, NULL); - - goto cleanup; - } trio_asprintf(&stmt, "delete from notif_jobs where notifid='%|Ss'", nid_s); edg_wll_ExecStmt(ctx, stmt, NULL); cleanup: - if ( owner ) free(owner); if ( nid_s ) free(nid_s); if ( stmt ) free(stmt); return edg_wll_Error(ctx, NULL, NULL); } + static char *get_user(edg_wll_Context ctx, int create) { edg_wll_Stmt stmt = NULL; @@ -320,7 +387,7 @@ static char *get_user(edg_wll_Context ctx, int create) if ( !ctx->peerName ) { - edg_wll_SetError(ctx, EPERM, "Annonymous notifications not allowed"); + edg_wll_SetError(ctx, EPERM, "Annonymous access not allowed"); goto cleanup; } trio_asprintf(&q, "select userid from users where cert_subj='%|Ss'", ctx->peerName); @@ -361,20 +428,18 @@ cleanup: return userid; } -static int update_notif( - edg_wll_Context ctx, - const edg_wll_NotifId nid, - const char *conds, - const char *dest, - const char *valid) + +static int check_notif_request( + edg_wll_Context ctx, + const edg_wll_NotifId nid, + char **owner) { - char *owner = NULL, - *nid_s = NULL, - *stmt, *aux; + char *nid_s = NULL, + *stmt, *user; int ret; - if ( !(owner = get_user(ctx, 0)) ) + if ( !(user = get_user(ctx, 0)) ) { if ( !edg_wll_Error(ctx, NULL, NULL) ) edg_wll_SetError(ctx, EPERM, "Unknown user"); @@ -385,10 +450,133 @@ static int update_notif( if ( !(nid_s = edg_wll_NotifIdGetUnique(nid)) ) goto cleanup; + trio_asprintf(&stmt, + "select notifid from notif_registrations " + "where notifid='%|Ss' and userid='%|Ss'", + nid_s, user); + + if ( (ret = edg_wll_ExecStmt(ctx, stmt, NULL)) < 0 ) + goto cleanup; + if ( ret == 0 ) + { + free(stmt); + trio_asprintf(&stmt, + "select notifid from notif_registrations where notifid='%|Ss'", nid_s); + ret = edg_wll_ExecStmt(ctx, stmt, NULL); + if ( ret == 0 ) + edg_wll_SetError(ctx, ENOENT, "Unknown notification ID"); + else if ( ret > 0 ) + edg_wll_SetError(ctx, EPERM, "Only owner could access the notification"); + } + +cleanup: + if ( !edg_wll_Error(ctx, NULL, NULL) && owner ) + *owner = user; + else + free(user); + if ( nid_s ) free(nid_s); + if ( stmt ) free(stmt); + + return edg_wll_Error(ctx, NULL, NULL); +} + + + /* Format conditions + * - first of all separate all jobids + * - then format new condition list without jobids and encode it into an XML string + */ +static int split_cond_list( + edg_wll_Context ctx, + edg_wll_QueryRec const * const *conditions, + edg_wll_QueryRec ***nconds_out, + char ***jobs_out) +{ + edg_wll_QueryRec **nconds = NULL; + char **jobs = NULL; + int i, j, jobs_ct, nconds_ct; + + + if ( !conditions || !conditions[0] ) + return edg_wll_SetError(ctx, EINVAL, "Empty condition list"); + + for ( nconds_ct = jobs_ct = i = 0; conditions[i]; i++ ) + { + if ( conditions[i][0].attr && conditions[i][0].attr != EDG_WLL_QUERY_ATTR_JOBID ) + nconds_ct++; + for ( j = 0; conditions[i][j].attr; j++ ) + if ( conditions[i][j].attr == EDG_WLL_QUERY_ATTR_JOBID ) + jobs_ct++; + } + + if ( jobs_out && jobs_ct ) + if ( !(jobs = calloc(jobs_ct+1, sizeof(char *))) ) + { + edg_wll_SetError(ctx, errno, NULL); + goto cleanup; + } + + if ( nconds_out && nconds_ct ) + if ( !(nconds = calloc(nconds_ct+1, sizeof(edg_wll_QueryRec *))) ) + { + edg_wll_SetError(ctx, errno, NULL); + goto cleanup; + } + + if ( jobs ) for ( jobs_ct = i = 0; conditions[i]; i++ ) + for ( j = 0; conditions[i][j].attr; j++ ) + if ( conditions[i][j].attr == EDG_WLL_QUERY_ATTR_JOBID ) + if ( !(jobs[jobs_ct++] = edg_wlc_JobIdGetUnique(conditions[i][j].value.j)) ) + { + edg_wll_SetError(ctx, errno, NULL); + goto cleanup; + } + + if ( nconds ) for ( nconds_ct = i = 0; conditions[i]; i++ ) + if ( conditions[i][0].attr && conditions[i][0].attr != EDG_WLL_QUERY_ATTR_JOBID ) + /* !!! DO NOT DEALLOCATE this arrays (it is not neccessary to allocate new + * mem - it's used only once and only for xml parsing + */ + nconds[nconds_ct++] = (edg_wll_QueryRec *) (conditions[i]); + + if ( jobs_out ) { *jobs_out = jobs; jobs = NULL; } + if ( nconds_out ) { *nconds_out = nconds; nconds = NULL; } + +cleanup: + if ( nconds ) free(nconds); + if ( jobs ) + { + for ( i = 0; jobs[i]; i++ ) + free(jobs[i]); + free(jobs); + } + + return edg_wll_Error(ctx, NULL, NULL); +} + + +static int update_notif( + edg_wll_Context ctx, + const edg_wll_NotifId nid, + const char *conds, + const char *dest, + const char *valid) +{ + char *nid_s = NULL, + *stmt, *aux; + int ret; + + + if ( !(nid_s = edg_wll_NotifIdGetUnique(nid)) ) + goto cleanup; + /* Format SQL update string * (Only the owner could update the notification registration) */ - stmt = strdup("update notif_registrations set"); + if ( !(stmt = strdup("update notif_registrations set")) ) + { + edg_wll_SetError(ctx, errno, "updating notification records"); + goto cleanup; + } if ( dest ) { trio_asprintf(&aux, "%s destination='%|Ss'", stmt, dest); @@ -403,13 +591,12 @@ static int update_notif( } if ( conds ) { - trio_asprintf(&aux, "%s %sconditions='%|Ss'", + trio_asprintf(&aux, "%s %sconditions='%|Ss'", stmt, (dest||valid)? ",": "", conds); free(stmt); stmt = aux; } - trio_asprintf(&aux, "%s where notifid='%|Ss' and userid='%|Ss'", - stmt, nid_s, owner); + trio_asprintf(&aux, "%s where notifid='%|Ss'", stmt, nid_s); free(stmt); stmt = aux; @@ -423,14 +610,19 @@ static int update_notif( ret = edg_wll_ExecStmt(ctx, stmt, NULL); if ( ret == 0 ) edg_wll_SetError(ctx, ENOENT, "Unknown notification ID"); + /* + * XXX: Be happy? + * May be: Rows matched: 1 Changed: 0 Warnings: 0 :-) else if ( ret > 0 ) edg_wll_SetError(ctx, EPERM, "Updating notification records"); + */ } cleanup: - if ( owner ) free(owner); if ( nid_s ) free(nid_s); if ( stmt ) free(stmt); return edg_wll_Error(ctx, NULL, NULL); } + + -- 1.8.2.3