FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
util.c
Go to the documentation of this file.
1 /********************************************************
2  Copyright (C) 2007-2013 Hewlett-Packard Development Company, L.P.
3  Copyright (C) 2015-2019 Siemens AG
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU General Public License
7  version 2 as published by the Free Software Foundation.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License along
15  with this program; if not, write to the Free Software Foundation, Inc.,
16  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 
18  ********************************************************/
26 #include "delagent.h"
27 
28 int Verbose = 0;
29 int Test = 0;
30 PGconn* pgConn = NULL; // the connection to Database
31 
38 int printfInCaseOfVerbosity (const char *format, ...)
39 {
40  va_list arg;
41  int done = 0;
42 
43  if (Verbose)
44  {
45  va_start (arg, format);
46  done = vprintf(format, arg);
47  va_end (arg);
48  }
49  return done;
50 }
51 
61 PGresult * PQexecCheck(const char *desc, char *SQL, char *file, const int line)
62 {
63  PGresult *result;
64 
65  if(desc == NULL)
66  {
67  printfInCaseOfVerbosity("# %s:%i: %s\n", file, line, SQL);
68  }
69  else
70  {
71  printfInCaseOfVerbosity("# %s:%i: %s (%s)\n", file, line, desc, SQL);
72  }
73 
74  result = PQexec(pgConn, SQL);
75  if (fo_checkPQcommand(pgConn, result, SQL, file, line))
76  {
77  exitNow(-1);
78  }
79  return result;
80 }
81 
86 void PQexecCheckClear(const char *desc, char *SQL, char *file, const int line)
87 {
88  PGresult *result;
89  result = PQexecCheck(desc, SQL, file, line);
90  PQclear(result);
91 }
92 
105 int authentication(char *user, char *password, int *userId, int *userPerm)
106 {
107  if (NULL == user || NULL == password)
108  {
109  return 1;
110  }
111  char SQL[MAXSQL] = {0};
112  PGresult *result;
113  char user_seed[myBUFSIZ] = {0};
114  char pass_hash_valid[41] = {0};
115  unsigned char pass_hash_actual_raw[21] = {0};
116  char pass_hash_actual[41] = {0};
117 
119  snprintf(SQL,MAXSQL,"SELECT user_seed, user_pass, user_perm, user_pk from users where user_name=$1;");
120  const char *values[1] = {user};
121  int lengths[1] = {strlen(user)};
122  int binary[1] = {0};
123  result = PQexecParams(pgConn, SQL, 1, NULL, values, lengths, binary, 0);
124  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
125  {
126  return -1;
127  }
128  if (!PQntuples(result))
129  {
130  return 1;
131  }
132  strcpy(user_seed, PQgetvalue(result, 0, 0));
133  strcpy(pass_hash_valid, PQgetvalue(result, 0, 1));
134  *userPerm = atoi(PQgetvalue(result, 0, 2));
135  *userId = atoi(PQgetvalue(result, 0, 3));
136  PQclear(result);
137  if (user_seed[0] && pass_hash_valid[0])
138  {
139  strcat(user_seed, password); // get the hash code on seed+pass
140  gcry_md_hash_buffer(GCRY_MD_SHA1, pass_hash_actual_raw, user_seed,
141  strlen(user_seed));
142  }
143  else
144  {
145  return -1;
146  }
147  int i = 0;
148  char temp[256] = {0};
149  for (i = 0; i < 20; i++)
150  {
151  snprintf(temp, 256, "%02x", pass_hash_actual_raw[i]);
152  strcat(pass_hash_actual, temp);
153  }
154  return (strcmp(pass_hash_valid, pass_hash_actual) == 0) ? 0 : 1;
155 }
156 
169 int check_permission_upload(int wanted_permissions, long uploadId, int userId, int userPerm)
170 {
171  int perms = getEffectivePermissionOnUpload(pgConn, uploadId, userId, userPerm);
172  if (perms > 0)
173  {
174  if (perms < wanted_permissions)
175  {
176  return 1;
177  }
178  else
179  {
180  return 0;
181  }
182  }
183  else if (perms == 0)
184  {
185  return 1;
186  }
187  return perms;
188 }
189 
200 int check_read_permission_upload(long uploadId, int userId, int userPerm)
201 {
202  return check_permission_upload(PERM_READ, uploadId, userId, userPerm);
203 }
204 
215 int check_write_permission_upload(long uploadId, int userId, int userPerm)
216 {
217  return check_permission_upload(PERM_WRITE, uploadId, userId, userPerm);
218 }
219 
232 int check_write_permission_folder(long folder_id, int userId, int userPerm)
233 {
234  char SQL[MAXSQL];
235  PGresult *result;
236  int count = 0;
237 
238  if (userPerm < PERM_WRITE)
239  {
240  return 1; // can not be deleted
241  }
242 
243  snprintf(SQL,MAXSQL,"SELECT count(*) FROM folder JOIN users ON (users.user_pk = folder.user_fk OR users.user_perm = 10) WHERE folder_pk = %ld AND users.user_pk = %d;",folder_id,userId);
244  result = PQexec(pgConn, SQL);
245  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
246  {
247  return -1;
248  }
249  count = atol(PQgetvalue(result,0,0));
250  if(count == 0)
251  {
252  return 1; // can not be deleted
253  }
254  return 0; // can be deleted
255 }
256 
267 int check_write_permission_license(long license_id, int userPerm)
268 {
269  if (userPerm != PERM_ADMIN)
270  {
271  printfInCaseOfVerbosity("only admin is allowed to delete licenses\n");
272  return 0; // can not be deleted
273  }
274  return 1; // can be deleted
275 }
276 
289 int deleteUpload (long uploadId, int userId, int userPerm)
290 {
291  char *S;
292  int Row,maxRow;
293  char tempTable[256];
294  PGresult *result, *pfileResult;
295  char SQL[MAXSQL], desc[myBUFSIZ];
296 
297  int permission_upload = check_write_permission_upload(uploadId, userId, userPerm);
298  if(0 != permission_upload) {
299  return permission_upload;
300  }
301 
302  snprintf(tempTable,sizeof(tempTable),"DelUp_%ld_pfile",uploadId);
303  snprintf(SQL,MAXSQL,"DROP TABLE IF EXISTS %s;",tempTable);
304  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
305 
306  snprintf(desc, myBUFSIZ, "Deleting upload %ld",uploadId);
307  PQexecCheckClear(desc, "SET statement_timeout = 0;", __FILE__, __LINE__);
308  PQexecCheckClear(NULL, "BEGIN;", __FILE__, __LINE__);
309 
310  /* Delete everything that impacts the UI */
311  if (!Test) {
312  /* The UI depends on uploadtree and folders for navigation.
313  Delete them now to block timeouts from the UI. */
314  PQexecCheckClear(NULL, "COMMIT;", __FILE__, __LINE__);
315  }
316 
317  /* Begin complicated stuff */
318  /* Get the list of pfiles to delete */
319  /* These are all pfiles in the upload_fk that only appear once. */
320  snprintf(SQL,MAXSQL,"SELECT DISTINCT pfile_pk,pfile_sha1 || '.' || pfile_md5 || '.' || pfile_size AS pfile INTO %s FROM uploadtree INNER JOIN pfile ON upload_fk = %ld AND pfile_fk = pfile_pk;",tempTable,uploadId);
321  PQexecCheckClear("Getting list of pfiles to delete", SQL, __FILE__, __LINE__);
322 
323  /* Remove pfiles which are reused by other uploads */
324  snprintf(SQL, MAXSQL, "DELETE FROM %s WHERE pfile_pk IN (SELECT pfile_pk FROM %s INNER JOIN uploadtree ON pfile_pk = pfile_fk WHERE upload_fk != %ld)", tempTable, tempTable, uploadId);
325  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
326 
327  if (Verbose) {
328  snprintf(SQL,MAXSQL,"SELECT COUNT(*) FROM %s;",tempTable);
329  result = PQexec(pgConn, SQL);
330  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__)) {
331  return -1;
332  }
333  printf("# Created pfile table %s with %ld entries\n", tempTable, atol(PQgetvalue(result,0,0)));
334  PQclear(result);
335  }
336 
337  /* Now to delete the actual pfiles from the repository before remove the DB. */
338  /* Get the file listing -- needed for deleting pfiles from the repository. */
339  snprintf(SQL,MAXSQL,"SELECT * FROM %s ORDER BY pfile_pk;",tempTable);
340  pfileResult = PQexec(pgConn, SQL);
341  if (fo_checkPQresult(pgConn, pfileResult, SQL, __FILE__, __LINE__)) {
342  return -1;
343  }
344 
345  if (Test <= 1) {
346  maxRow = PQntuples(pfileResult);
347  for(Row=0; Row<maxRow; Row++) {
348  S = PQgetvalue(pfileResult,Row,1); /* sha1.md5.len */
349  if (fo_RepExist("files",S)) {
350  if (Test) {
351  printf("TEST: Delete %s %s\n","files",S);
352  } else {
353  fo_RepRemove("files",S);
354  }
355  }
356  if (fo_RepExist("gold",S)) {
357  if (Test) {
358  printf("TEST: Delete %s %s\n","gold",S);
359  } else {
360  fo_RepRemove("gold",S);
361  }
362  }
364  }
365  }
366  PQclear(pfileResult);
367 
368  /*
369  This begins the slow part that locks the DB.
370  The problem is, we don't want to lock a critical row,
371  otherwise the scheduler will lock and/or fail.
372  */
373  if (!Test) {
374  PQexecCheckClear(NULL, "BEGIN;", __FILE__, __LINE__);
375  }
376  /* Delete the upload from the folder-contents table */
377  snprintf(SQL,MAXSQL,"DELETE FROM foldercontents WHERE (foldercontents_mode & 2) != 0 AND child_id = %ld;",uploadId);
378  PQexecCheckClear("Deleting foldercontents", SQL, __FILE__, __LINE__);
379 
380  /* Deleting the actual upload contents*/
381  /* Delete the bucket_container record as it can't be cascade delete with upload table */
382  snprintf(SQL,MAXSQL,"DELETE FROM bucket_container USING uploadtree WHERE uploadtree_fk = uploadtree_pk AND upload_fk = %ld;",uploadId);
383  PQexecCheckClear("Deleting bucket_container", SQL, __FILE__, __LINE__);
384 
385  /* Delete the tag_uploadtree record as it can't be cascade delete with upload table */
386  snprintf(SQL,MAXSQL,"DELETE FROM tag_uploadtree USING uploadtree WHERE uploadtree_fk = uploadtree_pk AND upload_fk = %ld;",uploadId);
387  PQexecCheckClear("Deleting tag_uploadtree", SQL, __FILE__, __LINE__);
388 
389  /* Delete uploadtree_nnn table */
390  char uploadtree_tablename[1000];
391  snprintf(SQL,MAXSQL,"SELECT uploadtree_tablename FROM upload WHERE upload_pk = %ld;",uploadId);
392  result = PQexec(pgConn, SQL);
393  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__)) {
394  return -1;
395  }
396  if (PQntuples(result)) {
397  strcpy(uploadtree_tablename, PQgetvalue(result, 0, 0));
398  PQclear(result);
399  if (strcasecmp(uploadtree_tablename,"uploadtree_a")) {
400  snprintf(SQL,MAXSQL,"DROP TABLE %s;", uploadtree_tablename);
401  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
402  }
403  }
404 
405  printfInCaseOfVerbosity("Deleting license decisions for upload %ld\n",uploadId);
406  /* delete from clearing_decision_event table. */
407  snprintf(SQL, MAXSQL, "DELETE FROM clearing_decision_event USING clearing_event WHERE clearing_decision_event.clearing_event_fk = clearing_event.clearing_event_pk AND clearing_event.uploadtree_fk IN (SELECT uploadtree_pk FROM uploadtree INNER JOIN %s ON uploadtree.pfile_fk = %s.pfile_pk WHERE upload_fk = %ld);", tempTable, tempTable, uploadId);
408  PQexecCheckClear("Deleting from clearing_decision_event", SQL, __FILE__, __LINE__);
409 
410  /* delete from clearing_event table. */
411  snprintf(SQL, MAXSQL, "DELETE FROM clearing_event WHERE uploadtree_fk IN (SELECT uploadtree_pk FROM uploadtree INNER JOIN %s ON uploadtree.pfile_fk = %s.pfile_pk WHERE upload_fk = %ld);", tempTable, tempTable, uploadId);
412  PQexecCheckClear("Deleting from clearing_event", SQL, __FILE__, __LINE__);
413 
414  /* delete from uploadtree table. */
415  snprintf(SQL, MAXSQL, "DELETE FROM uploadtree WHERE upload_fk = %ld;", uploadId);
416  PQexecCheckClear("Deleting from uploadtree", SQL, __FILE__, __LINE__);
417 
418  /* delete from pfile is SLOW due to constraint checking. Do it separately. */
419  snprintf(SQL,MAXSQL,"DELETE FROM pfile USING %s WHERE pfile.pfile_pk = %s.pfile_pk;",tempTable,tempTable);
420  PQexecCheckClear("Deleting from pfile", SQL, __FILE__, __LINE__);
421 
422  snprintf(SQL,MAXSQL,"DROP TABLE %s;",tempTable);
423  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
424 
425  /* Mark upload deleted in upload table */
426  snprintf(SQL,MAXSQL,"UPDATE upload SET expire_action = 'd', "
427  "expire_date = now(), pfile_fk = NULL WHERE upload_pk = %ld;", uploadId);
428  PQexecCheckClear("Marking upload as deleted", SQL, __FILE__, __LINE__);
429 
430  PQexecCheckClear(NULL, "SET statement_timeout = 120000;", __FILE__, __LINE__);
431 
432  printfInCaseOfVerbosity("Deleted upload %ld from DB, now doing repository.\n",uploadId);
433 
434  if (Test) {
435  PQexecCheckClear(NULL, "ROLLBACK;", __FILE__, __LINE__);
436  } else {
437  PQexecCheckClear(NULL, "COMMIT;", __FILE__, __LINE__);
438  }
439 
440  printfInCaseOfVerbosity("Deleted upload %ld\n",uploadId);
441 
442  return 0; /* success */
443 } /* deleteUpload() */
444 
458 int unlinkContent (long child, long parent, int mode, int userId, int userPerm)
459 {
460  int cnt, cntUpload;
461  char SQL[MAXSQL];
462  PGresult *result;
463 
464  if(mode == 1){
465  snprintf(SQL,MAXSQL,"SELECT COUNT(DISTINCT parent_fk) FROM foldercontents WHERE foldercontents_mode=%d AND child_id=%ld",mode,child);
466  }
467  else{
468  snprintf(SQL,MAXSQL,"SELECT COUNT(parent_fk) FROM foldercontents WHERE foldercontents_mode=%d AND"
469  " child_id in (SELECT upload_pk FROM folderlist WHERE pfile_fk="
470  "(SELECT pfile_fk FROM folderlist WHERE upload_pk=%ld limit 1))",
471  mode,child);
472  }
473  result = PQexec(pgConn, SQL);
474  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
475  {
476  return -1;
477  }
478  cnt = atoi(PQgetvalue(result,0,0));
479  PQclear(result);
480  if(cnt>1 && !Test)
481  {
482  if(mode == 2){
483  snprintf(SQL,MAXSQL,"SELECT COUNT(DISTINCT parent_fk) FROM foldercontents WHERE foldercontents_mode=1 AND child_id=%ld",parent);
484  result = PQexec(pgConn, SQL);
485  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
486  {
487  return -1;
488  }
489  cntUpload = atoi(PQgetvalue(result,0,0));
490  PQclear(result);
491  if(cntUpload > 1){ // check for copied/duplicate folder
492  return 0;
493  }
494  }
495  snprintf(SQL,MAXSQL,"DELETE FROM foldercontents WHERE foldercontents_mode=%d AND child_id =%ld AND parent_fk=%ld",mode,child,parent);
496  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
497  return 0;
498  }
499  return 1;
500 }
501 
520 int listFoldersRecurse (long Parent, int Depth, long Row, int DelFlag, int userId, int userPerm)
521 {
522  int r, i, rc, maxRow;
523  int count, resultUploadCount;
524  long Fid;
525  char *Desc;
526  char SQL[MAXSQL], SQLUpload[MAXSQL];
527  char SQLFolder[MAXSQLFolder];
528  PGresult *result, *resultUpload, *resultFolder;
529 
530  rc = check_write_permission_folder(Parent, userId, userPerm);
531  if(rc < 0)
532  {
533  return rc;
534  }
535  if(DelFlag && rc > 0){
536  return 1;
537  }
538 
539  snprintf(SQLFolder, MAXSQLFolder,"SELECT COUNT(*) FROM folderlist WHERE folder_pk=%ld",Parent);
540  resultFolder = PQexec(pgConn, SQLFolder);
541  count= atoi(PQgetvalue(resultFolder,0,0));
542  PQclear(resultFolder);
543 
544  /* Find all folders with this parent and recurse, but don't show uploads, if they also exist in other directories */
545  snprintf(SQL,MAXSQL,"SELECT folder_pk,foldercontents_mode,name,description,upload_pk,pfile_fk FROM folderlist WHERE parent=%ld"
546  " ORDER BY name,parent,folder_pk ", Parent);
547  result = PQexec(pgConn, SQL);
548  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
549  {
550  return -1;
551  }
552  maxRow = PQntuples(result);
553  for(r=0; r < maxRow; r++)
554  {
555  if (atol(PQgetvalue(result,r,0)) == Parent)
556  {
557  continue;
558  }
559 
560  Fid = atol(PQgetvalue(result,r,0));
561  if (Fid != 0)
562  {
563  if (!DelFlag)
564  {
565  for(i=0; i<Depth; i++)
566  {
567  fputs(" ",stdout);
568  }
569  printf("%4ld :: %s",Fid,PQgetvalue(result,r,2));
570  Desc = PQgetvalue(result,r,3);
571  if (Desc && Desc[0])
572  {
573  printf(" (%s)",Desc);
574  }
575  printf("\n");
576  }
577  rc = listFoldersRecurse(Fid,Depth+1,Parent,DelFlag,userId,userPerm);
578  if (rc < 0)
579  {
580  if (DelFlag)
581  {
582  printf("Deleting the folder failed.");
583  }
584  return 1;
585  }
586  }
587  else
588  {
589  if (DelFlag==1 && unlinkContent(Parent,Row,1,userId,userPerm)==0)
590  {
591  continue;
592  }
593  if (rc < 0)
594  {
595  return rc;
596  }
597  if (DelFlag)
598  {
599  snprintf(SQLUpload, MAXSQL,"SELECT COUNT(*) FROM folderlist WHERE pfile_fk=%ld", atol(PQgetvalue(result,r,5)));
600  resultUpload = PQexec(pgConn, SQLUpload);
601  resultUploadCount = atoi(PQgetvalue(resultUpload,0,0));
602  if(count < 2 && resultUploadCount < 2)
603  {
604  rc = deleteUpload(atol(PQgetvalue(result,r,4)),userId, userPerm);
605  if (rc < 0)
606  {
607  return rc;
608  }
609  if (rc != 0)
610  {
611  printf("Deleting the folder failed since it contains uploads you can't delete.");
612  return rc;
613  }
614  }
615  else{
616  rc = unlinkContent(atol(PQgetvalue(result,r,4)),Parent,2,userId,userPerm);
617  if(rc < 0){
618  return rc;
619  }
620  }
621  }
622  else
623  {
624  rc = check_read_permission_upload(atol(PQgetvalue(result,r,4)),userId,userPerm);
625  if (rc < 0)
626  {
627  return rc;
628  }
629  if (rc == 0)
630  {
631  for(i=0; i<Depth; i++)
632  {
633  fputs(" ",stdout);
634  }
635  printf("%4s :: Contains: %s\n","--",PQgetvalue(result,r,2));
636  }
637  }
638  }
639  }
640  PQclear(result);
641 
642  switch(Parent)
643  {
644  case 1: /* skip default parent */
645  if (DelFlag != 0)
646  {
647  printf("INFO: Default folder not deleted.\n");
648  }
649  break;
650  case 0: /* it's an upload */
651  break;
652  default: /* it's a folder */
653  if (DelFlag == 0)
654  {
655  break;
656  }
657  printf("INFO: folder id=%ld will be deleted with flag %d\n",Parent,DelFlag);
658  if (DelFlag==1)
659  {
660  rc = unlinkContent(Parent,Row,1,userId,userPerm);
661  if (rc == 0)
662  {
663  break;
664  }
665  if (rc < 0)
666  {
667  return rc;
668  }
669  }
670  if(Row > 0)
671  snprintf(SQL,MAXSQL,"DELETE FROM foldercontents WHERE foldercontents_mode=1 AND parent_fk=%ld AND child_id=%ld",Row,Parent);
672  else
673  snprintf(SQL,MAXSQL,"DELETE FROM foldercontents WHERE foldercontents_mode=1 AND child_id=%ld",Parent);
674  if (Test)
675  {
676  printf("TEST: %s\n",SQL);
677  }
678  else
679  {
680  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
681  }
682  if(Row > 0)
683  snprintf(SQL,MAXSQL,"DELETE FROM folder f USING foldercontents fc WHERE f.folder_pk = fc.child_id AND fc.parent_fk='%ld' AND f.folder_pk = '%ld';",Row,Parent);
684  else
685  snprintf(SQL,MAXSQL,"DELETE FROM folder WHERE folder_pk = '%ld';",Parent);
686  if (Test)
687  {
688  printf("TEST: %s\n",SQL);
689  }
690  else
691  {
692  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
693  }
694  } /* switch() */
695 
696  return 0; /* success */
697 } /* listFoldersRecurse() */
698 
708 int listFoldersFindDetatchedFolders(PGresult *result, int userId, int userPerm)
709 {
710  int DetachFlag=0;
711  int i,j;
712  int maxRow = PQntuples(result);
713  long Fid; /* folder ids */
714  int Match;
715  char *Desc;
716  int rc;
717 
718  /* Find detached folders */
719  for(i=0; i < maxRow; i++)
720  {
721  Fid = atol(PQgetvalue(result,i,1));
722  if (Fid == 1)
723  {
724  continue; /* skip default parent */
725  }
726  Match=0;
727  for(j=0; (j<maxRow) && !Match; j++)
728  {
729  if ((i!=j) && (atol(PQgetvalue(result,j,0)) == Fid)) Match=1;
730  }
731  if (!Match && !atol(PQgetvalue(result,i,4)))
732  {
733  if (!DetachFlag)
734  {
735  printf("# Unlinked folders\n");
736  DetachFlag=1;
737  }
738  printf("%4ld :: %s",Fid,PQgetvalue(result,i,2));
739  Desc = PQgetvalue(result,i,3);
740  if (Desc && Desc[0])
741  {
742  printf(" (%s)",Desc);
743  }
744  printf("\n");
745  rc = listFoldersRecurse(Fid,1,i,0,userId,userPerm);
746  if (rc < 0)
747  {
748  return rc;
749  }
750  }
751  }
752  return 0;
753 }
754 
762 int listFoldersFindDetatchedUploads(PGresult *result, int userId, int userPerm)
763 {
764  int DetachFlag=0;
765  int i,j;
766  int maxRow = PQntuples(result);
767  long Fid; /* folder ids */
768  int Match;
769  char *Desc;
770  /* Find detached uploads */
771  for(i=0; i < maxRow; i++)
772  {
773  Fid = atol(PQgetvalue(result,i,1));
774  if (Fid == 1)
775  {
776  continue; /* skip default parent */
777  }
778  Match=0;
779  for(j=0; (j<maxRow) && !Match; j++)
780  {
781  if ((i!=j) && (atol(PQgetvalue(result,j,0)) == Fid)) Match=1;
782  }
783  if (!Match && atol(PQgetvalue(result,i,4)))
784  {
785  if (!DetachFlag)
786  {
787  printf("# Unlinked uploads (uploads without folders)\n");
788  DetachFlag=1;
789  }
790  printf("%4s",PQgetvalue(result,i,4));
791  printf(" :: %s",PQgetvalue(result,i,2));
792  Desc = PQgetvalue(result,i,3);
793  if (Desc && Desc[0])
794  {
795  printf(" (%s)",Desc);
796  }
797  printf("\n");
798  }
799  }
800  return 0;
801 }
802 
811 int listFoldersFindDetatched(int userId, int userPerm)
812 {
813  char SQL[MAXSQL];
814  PGresult *result;
815  int rc;
816 
817  snprintf(SQL,MAXSQL,"SELECT folder_pk,parent,name,description,upload_pk FROM folderlist ORDER BY name,parent,folder_pk;");
818  result = PQexec(pgConn, SQL);
819  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
820  {
821  return -1;
822  }
823  rc = listFoldersFindDetatchedFolders(result, userId, userPerm);
824  if (rc < 0 )
825  {
826  PQclear(result);
827  return rc;
828  }
829  rc = listFoldersFindDetatchedUploads(result, userId, userPerm);
830  PQclear(result);
831  if (rc < 0 )
832  {
833  return rc;
834  }
835  return 0;
836 }
837 
843 int listFolders (int userId, int userPerm)
844 {
845  char SQL[MAXSQL];
846  PGresult *result;
847  int rc;
848 
849  if(userPerm == 0){
850  printf("you do not have the permsssion to view the folder list.\n");
851  return 1;
852  }
853 
854  printf("# Folders\n");
855  snprintf(SQL,MAXSQL,"SELECT folder_name from folder where folder_pk =1;");
856  result = PQexec(pgConn, SQL);
857  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
858  {
859  return -1;
860  }
861 
862  printf("%4d :: %s\n", 1, PQgetvalue(result,0,0));
863  PQclear(result);
864 
865  rc = listFoldersRecurse(1,1,-1,0,userId,userPerm);
866  if (rc < 0)
867  {
868  return rc;
869  }
870 
871  rc = listFoldersFindDetatched(userId, userPerm);
872  if (rc < 0)
873  {
874  return rc;
875  }
876  return 0;
877 } /* listFolders() */
878 
886 int listUploads (int userId, int userPerm)
887 {
888  int Row,maxRow;
889  long NewPid;
890  PGresult *result;
891  int rc;
892  char *SQL = "SELECT upload_pk,upload_desc,upload_filename FROM upload ORDER BY upload_pk;";
893  printf("# Uploads\n");
894  result = PQexec(pgConn, SQL);
895  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
896  {
897  exitNow(-1);
898  }
899 
900  /* list each value */
901  maxRow = PQntuples(result);
902  for(Row=0; Row < maxRow; Row++)
903  {
904  NewPid = atol(PQgetvalue(result,Row,0));
905  rc = check_read_permission_upload(NewPid, userId, userPerm);
906  if (rc < 0)
907  {
908  PQclear(result);
909  return rc;
910  }
911  if (NewPid >= 0 && (userPerm == PERM_ADMIN || rc == 0))
912  {
913  char *S;
914  printf("%ld :: %s",NewPid,PQgetvalue(result,Row,2));
915  S = PQgetvalue(result,Row,1);
916  if (S && S[0]) printf(" (%s)",S);
917  printf("\n");
918  }
919  }
920  PQclear(result);
921  return 0;
922 } /* listUploads() */
923 
940 int deleteFolder(long cFolder, long pFolder, int userId, int userPerm)
941 {
942  if(pFolder == 0) pFolder= -1 ;
943  return listFoldersRecurse(cFolder, 0,pFolder,2,userId,userPerm);
944 } /* deleteFolder() */
945 
946 /**********************************************************************/
947 
964 int readAndProcessParameter (char *Parm, int userId, int userPerm)
965 {
966  char *L;
967  int rc=0; /* assume no data */
968  int Type=0; /* 0=undefined; 1=delete; 2=list */
969  int Target=0; /* 0=undefined; 1=upload; 2=license; 3=folder */
970  const char s[2] = " ";
971  char *token;
972  char a[15];
973  long fd[2];
974  int i = 0, len = 0;
975 
976  if (!Parm)
977  {
978  return(-1);
979  }
980  if (Verbose > 1) fprintf(stderr,"DEBUG: Line='%s'\n",Parm);
981 
982  /* process the string. */
983  L = Parm;
984  while(isspace(L[0])) L++;
985 
987  if (!strncasecmp(L,"DELETE",6) && isspace(L[6]))
988  {
989  Type=1; /* delete */
990  L+=6;
991  }
992  else if (!strncasecmp(L,"LIST",4) && isspace(L[4]))
993  {
994  Type=2; /* list */
995  L+=4;
996  }
997  while(isspace(L[0])) L++;
999  if (!strncasecmp(L,"UPLOAD",6) && (isspace(L[6]) || !L[6]))
1000  {
1001  Target=1; /* upload */
1002  L+=6;
1003  }
1004  else if (!strncasecmp(L,"LICENSE",7) && (isspace(L[7]) || !L[7]))
1005  {
1006  Target=2; /* license */
1007  L+=7;
1008  }
1009  else if (!strncasecmp(L,"FOLDER",6) && (isspace(L[6]) || !L[6]))
1010  {
1011  Target=3; /* folder */
1012  L+=6;
1013  }
1014 
1015  len = strlen(L);
1016  memcpy(a, L,len);
1017  token = strtok(a, s);
1018 
1019  while( token != NULL )
1020  {
1021  fd[i] = atol(token);
1022  token = strtok(NULL, s);
1023  i++;
1024  }
1025 
1026  /* Handle the request */
1027  if ((Type==1) && (Target==1))
1028  {
1029  rc = deleteUpload(fd[0], userId, userPerm);
1030  }
1031  else if ((Type==1) && (Target==3))
1032  {
1033  rc = deleteFolder(fd[1],fd[0], userId, userPerm);
1034  }
1035  else if (((Type==2) && (Target==1)) || ((Type==2) && (Target==2)))
1036  {
1037  rc = listUploads(0, PERM_ADMIN);
1038  }
1039  else if ((Type==2) && (Target==3))
1040  {
1041  rc = listFolders(userId, userPerm);
1042  }
1043  else
1044  {
1045  LOG_ERROR("Unknown command: '%s'\n",Parm);
1046  }
1047 
1048  return rc;
1049 } /* readAndProcessParameter() */
1050 
1061 {
1062  char *Parm = NULL;
1063  char SQL[MAXSQL];
1064  PGresult *result;
1065  int userId = -1;
1066  int userPerm = -1;
1067 
1068  while(fo_scheduler_next())
1069  {
1070  Parm = fo_scheduler_current();
1071  userId = fo_scheduler_userID();
1072 
1073  /* get perm level of user */
1074  snprintf(SQL,MAXSQL,"SELECT user_perm FROM users WHERE user_pk='%d';", userId);
1075  result = PQexec(pgConn, SQL);
1076  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__) || !PQntuples(result))
1077  {
1078  exitNow(0);
1079  }
1080  userPerm = atoi(PQgetvalue(result, 0, 0));
1081  PQclear(result);
1082 
1083  int returnCode = readAndProcessParameter(Parm, userId, userPerm);
1084  if (returnCode != 0)
1085  {
1086  /* Loglevel is to high, but scheduler expects FATAL log message before exit */
1087  LOG_FATAL("Due to permission problems, the delagent was not able to list or delete the requested objects or they did not exist.");
1088  exitNow(returnCode);
1089  }
1090  }
1091 }
1099 void exitNow(int exitVal)
1100 {
1101  if (pgConn) PQfinish(pgConn);
1102 
1103  if (exitVal) LOG_ERROR("Exiting with status %d", exitVal);
1104 
1105  fo_scheduler_disconnect(exitVal);
1106  exit(exitVal);
1107 } /* exitNow() */
int Test
Definition: util.c:29
int fo_checkPQresult(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres SELECT.
Definition: libfossdb.c:181
int listFoldersFindDetatched(int userId, int userPerm)
Given a user id, find detached folders and uploads.
Definition: util.c:811
Definition: match.h:31
int deleteFolder(long cFolder, long pFolder, int userId, int userPerm)
recursively delete a folder
Definition: util.c:940
int check_permission_upload(int wanted_permissions, long uploadId, int userId, int userPerm)
check if the upload can be deleted, that is the user have the permission to delete this upload ...
Definition: util.c:169
void doSchedulerTasks()
process the jobs from scheduler
Definition: util.c:1060
int Verbose
Verbose level.
Definition: util.c:28
int s
The socket that the CLI will use to communicate.
Definition: fo_cli.c:48
char * fo_scheduler_current()
Get the last read string from the scheduler.
int check_write_permission_folder(long folder_id, int userId, int userPerm)
check if the upload can be deleted, that is the user have the permission to delete this upload ...
Definition: util.c:232
void fo_scheduler_disconnect(int retcode)
Disconnect the scheduler connection.
int readAndProcessParameter(char *Parm, int userId, int userPerm)
Parse parameters.
Definition: util.c:964
int check_read_permission_upload(long uploadId, int userId, int userPerm)
check if the user has read permission on the given upload
Definition: util.c:200
int listFoldersFindDetatchedFolders(PGresult *result, int userId, int userPerm)
Given a PGresult, find detached folders.
Definition: util.c:708
int check_write_permission_license(long license_id, int userPerm)
check if the license can be deleted, that is the user have the permission to delete this license ...
Definition: util.c:267
int printfInCaseOfVerbosity(const char *format,...)
If verbose is on, print to stdout.
Definition: util.c:38
int fo_checkPQcommand(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres commands (not select) If an error occured, write the error to s...
Definition: libfossdb.c:215
int listFoldersFindDetatchedUploads(PGresult *result, int userId, int userPerm)
Given a PGresult, find detached uploads.
Definition: util.c:762
int check_write_permission_upload(long uploadId, int userId, int userPerm)
check if the user has read permission on the given upload
Definition: util.c:215
char SQL[256]
SQL query to execute.
Definition: adj2nest.c:90
PGresult * PQexecCheck(const char *desc, char *SQL, char *file, const int line)
simple wrapper which includes PQexec and fo_checkPQcommand
Definition: util.c:61
int deleteUpload(long uploadId, int userId, int userPerm)
Given an upload ID, delete it.
Definition: util.c:289
int fo_scheduler_userID()
Gets the id of the user that created the job that the agent is running.
PGconn * pgConn
Database connection.
Definition: util.c:30
FUNCTION int getEffectivePermissionOnUpload(PGconn *pgConn, long UploadPk, int user_pk, int user_perm)
Get users permission to this upload.
Definition: libfossagent.c:335
char * uploadtree_tablename
upload.uploadtree_tablename
Definition: adj2nest.c:112
#define PERM_READ
Read-only permission.
Definition: libfossology.h:44
char * fo_scheduler_next()
Get the next data to process from the scheduler.
void fo_scheduler_heart(int i)
This function must be called by agents to let the scheduler know they are alive and how many items th...
int unlinkContent(long child, long parent, int mode, int userId, int userPerm)
remove link between parent and (child,mode) if there are other parents
Definition: util.c:458
int listFoldersRecurse(long Parent, int Depth, long Row, int DelFlag, int userId, int userPerm)
Draw folder tree.
Definition: util.c:520
int listFolders(int userId, int userPerm)
List every folder.
Definition: util.c:843
void exitNow(int exitVal)
Exit function. This does all cleanup and should be used instead of calling exit() or main() return...
Definition: util.c:1099
void PQexecCheckClear(const char *desc, char *SQL, char *file, const int line)
Execute SQL query and create the result.
Definition: util.c:86
int authentication(char *user, char *password, int *userId, int *userPerm)
if this account is valid
Definition: util.c:105
int listUploads(int userId, int userPerm)
List every upload ID.
Definition: util.c:886
#define PERM_ADMIN
Administrator.
Definition: libfossology.h:46
#define PERM_WRITE
Read-Write permission.
Definition: libfossology.h:45
int fo_RepRemove(char *Type, char *Filename)
Delete a repository file.
Definition: libfossrepo.c:580
int fo_RepExist(char *Type, char *Filename)
Determine if a file exists.
Definition: libfossrepo.c:498