FOSSology  4.4.0
Open Source License Compliance by Open Source Software
util.c
Go to the documentation of this file.
1 /*
2  SPDX-FileCopyrightText: © 2007-2013 Hewlett-Packard Development Company, L.P.
3  SPDX-FileCopyrightText: © 2015-2019 Siemens AG
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
15 #include <crypt.h>
16 
17 #include "delagent.h"
18 
19 int Verbose = 0;
20 int Test = 0;
21 PGconn* pgConn = NULL; // the connection to Database
22 
29 int printfInCaseOfVerbosity (const char *format, ...)
30 {
31  va_list arg;
32  int done = 0;
33 
34  if (Verbose)
35  {
36  va_start (arg, format);
37  done = vprintf(format, arg);
38  va_end (arg);
39  }
40  return done;
41 }
42 
52 PGresult * PQexecCheck(const char *desc, char *SQL, char *file, const int line)
53 {
54  PGresult *result;
55 
56  if(desc == NULL)
57  {
58  printfInCaseOfVerbosity("# %s:%i: %s\n", file, line, SQL);
59  }
60  else
61  {
62  printfInCaseOfVerbosity("# %s:%i: %s (%s)\n", file, line, desc, SQL);
63  }
64 
65  result = PQexec(pgConn, SQL);
66  if (fo_checkPQcommand(pgConn, result, SQL, file, line))
67  {
68  exitNow(-1);
69  }
70  return result;
71 }
72 
77 void PQexecCheckClear(const char *desc, char *SQL, char *file, const int line)
78 {
79  PGresult *result;
80  result = PQexecCheck(desc, SQL, file, line);
81  PQclear(result);
82 }
83 
96 int authentication(char *user, char *password, int *userId, int *userPerm)
97 {
98  if (NULL == user || NULL == password)
99  {
100  return 1;
101  }
102  char SQL[MAXSQL] = {0};
103  PGresult *result;
104  char user_seed[myBUFSIZ] = {0};
105  char pass_hash_valid[myBUFSIZ] = {0};
106  unsigned char pass_hash_actual_raw[21] = {0};
107  char pass_hash_actual[41] = {0};
108 
110  snprintf(SQL,MAXSQL,"SELECT user_seed, user_pass, user_perm, user_pk from users where user_name=$1;");
111  const char *values[1] = {user};
112  int lengths[1] = {strlen(user)};
113  int binary[1] = {0};
114  result = PQexecParams(pgConn, SQL, 1, NULL, values, lengths, binary, 0);
115  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
116  {
117  return -1;
118  }
119  if (!PQntuples(result))
120  {
121  return 1;
122  }
123  strcpy(user_seed, PQgetvalue(result, 0, 0));
124  strcpy(pass_hash_valid, PQgetvalue(result, 0, 1));
125  *userPerm = atoi(PQgetvalue(result, 0, 2));
126  *userId = atoi(PQgetvalue(result, 0, 3));
127  PQclear(result);
128  if (pass_hash_valid[0] &&
129  strcmp(crypt(password, pass_hash_valid), pass_hash_valid) == 0)
130  {
131  return 0;
132  }
133  if (user_seed[0] && pass_hash_valid[0])
134  {
135  strcat(user_seed, password); // get the hash code on seed+pass
136  gcry_md_hash_buffer(GCRY_MD_SHA1, pass_hash_actual_raw, user_seed,
137  strlen(user_seed));
138  }
139  else
140  {
141  return -1;
142  }
143  int i = 0;
144  char temp[256] = {0};
145  for (i = 0; i < 20; i++)
146  {
147  snprintf(temp, 256, "%02x", pass_hash_actual_raw[i]);
148  strcat(pass_hash_actual, temp);
149  }
150  return (strcmp(pass_hash_valid, pass_hash_actual) == 0) ? 0 : 1;
151 }
152 
165 int check_permission_upload(int wanted_permissions, long uploadId, int userId, int userPerm)
166 {
167  int perms = getEffectivePermissionOnUpload(pgConn, uploadId, userId, userPerm);
168  if (perms > 0)
169  {
170  if (perms < wanted_permissions)
171  {
172  return 1;
173  }
174  else
175  {
176  return 0;
177  }
178  }
179  else if (perms == 0)
180  {
181  return 1;
182  }
183  return perms;
184 }
185 
196 int check_read_permission_upload(long uploadId, int userId, int userPerm)
197 {
198  return check_permission_upload(PERM_READ, uploadId, userId, userPerm);
199 }
200 
211 int check_write_permission_upload(long uploadId, int userId, int userPerm)
212 {
213  return check_permission_upload(PERM_WRITE, uploadId, userId, userPerm);
214 }
215 
228 int check_write_permission_folder(long folder_id, int userId, int userPerm)
229 {
230  char SQL[MAXSQL];
231  PGresult *result;
232  int count = 0;
233 
234  if (userPerm < PERM_WRITE)
235  {
236  return 1; // can not be deleted
237  }
238 
239  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);
240  result = PQexec(pgConn, SQL);
241  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
242  {
243  return -1;
244  }
245  count = atol(PQgetvalue(result,0,0));
246  if(count == 0)
247  {
248  return 1; // can not be deleted
249  }
250  return 0; // can be deleted
251 }
252 
263 int check_write_permission_license(long license_id, int userPerm)
264 {
265  if (userPerm != PERM_ADMIN)
266  {
267  printfInCaseOfVerbosity("only admin is allowed to delete licenses\n");
268  return 0; // can not be deleted
269  }
270  return 1; // can be deleted
271 }
272 
285 int deleteUpload (long uploadId, int userId, int userPerm)
286 {
287  char *S;
288  int Row,maxRow;
289  char tempTable[256];
290  PGresult *result, *pfileResult;
291  char SQL[MAXSQL], desc[myBUFSIZ];
292 
293  int permission_upload = check_write_permission_upload(uploadId, userId, userPerm);
294  if(0 != permission_upload) {
295  return permission_upload;
296  }
297 
298  snprintf(tempTable,sizeof(tempTable),"delup_%ld_pfile",uploadId);
299  snprintf(SQL,MAXSQL,"DROP TABLE IF EXISTS %s;",tempTable);
300  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
301 
302  snprintf(desc, myBUFSIZ, "Deleting upload %ld",uploadId);
303  PQexecCheckClear(desc, "SET statement_timeout = 0;", __FILE__, __LINE__);
304  PQexecCheckClear(NULL, "BEGIN;", __FILE__, __LINE__);
305 
306  /* Delete everything that impacts the UI */
307  if (!Test) {
308  /* The UI depends on uploadtree and folders for navigation.
309  Delete them now to block timeouts from the UI. */
310  PQexecCheckClear(NULL, "COMMIT;", __FILE__, __LINE__);
311  }
312 
313  /* Begin complicated stuff */
314  /* Get the list of pfiles to delete */
315  /* These are all pfiles in the upload_fk that only appear once. */
316  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);
317  PQexecCheckClear("Getting list of pfiles to delete", SQL, __FILE__, __LINE__);
318 
319  /* Remove pfiles which are reused by other uploads */
320  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);
321  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
322 
323  if (Verbose) {
324  snprintf(SQL,MAXSQL,"SELECT COUNT(*) FROM %s;",tempTable);
325  result = PQexec(pgConn, SQL);
326  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__)) {
327  return -1;
328  }
329  printf("# Created pfile table %s with %ld entries\n", tempTable, atol(PQgetvalue(result,0,0)));
330  PQclear(result);
331  }
332 
333  /* Now to delete the actual pfiles from the repository before remove the DB. */
334  /* Get the file listing -- needed for deleting pfiles from the repository. */
335  snprintf(SQL,MAXSQL,"SELECT pfile FROM %s ORDER BY pfile_pk;",tempTable);
336  pfileResult = PQexec(pgConn, SQL);
337  if (fo_checkPQresult(pgConn, pfileResult, SQL, __FILE__, __LINE__)) {
338  return -1;
339  }
340 
341  if (Test <= 1) {
342  maxRow = PQntuples(pfileResult);
343  for(Row=0; Row<maxRow; Row++) {
344  S = PQgetvalue(pfileResult,Row,0); /* sha1.md5.len */
345  if (fo_RepExist("files",S)) {
346  if (Test) {
347  printf("TEST: Delete %s %s\n","files",S);
348  } else {
349  fo_RepRemove("files",S);
350  }
351  }
352  if (fo_RepExist("gold",S)) {
353  if (Test) {
354  printf("TEST: Delete %s %s\n","gold",S);
355  } else {
356  fo_RepRemove("gold",S);
357  }
358  }
360  }
361  }
362  PQclear(pfileResult);
363 
364  /*
365  This begins the slow part that locks the DB.
366  The problem is, we don't want to lock a critical row,
367  otherwise the scheduler will lock and/or fail.
368  */
369  if (!Test) {
370  PQexecCheckClear(NULL, "BEGIN;", __FILE__, __LINE__);
371  }
372  /* Delete the upload from the folder-contents table */
373  snprintf(SQL,MAXSQL,"DELETE FROM foldercontents WHERE (foldercontents_mode & 2) != 0 AND child_id = %ld;",uploadId);
374  PQexecCheckClear("Deleting foldercontents", SQL, __FILE__, __LINE__);
375 
376  /* Deleting the actual upload contents*/
377  /* Delete the bucket_container record as it can't be cascade delete with upload table */
378  snprintf(SQL,MAXSQL,"DELETE FROM bucket_container USING uploadtree WHERE uploadtree_fk = uploadtree_pk AND upload_fk = %ld;",uploadId);
379  PQexecCheckClear("Deleting bucket_container", SQL, __FILE__, __LINE__);
380 
381  /* Delete the tag_uploadtree record as it can't be cascade delete with upload table */
382  snprintf(SQL,MAXSQL,"DELETE FROM tag_uploadtree USING uploadtree WHERE uploadtree_fk = uploadtree_pk AND upload_fk = %ld;",uploadId);
383  PQexecCheckClear("Deleting tag_uploadtree", SQL, __FILE__, __LINE__);
384 
385  char uploadtree_tablename[1000];
386  snprintf(SQL,MAXSQL,"SELECT uploadtree_tablename FROM upload WHERE upload_pk = %ld;",uploadId);
387  result = PQexec(pgConn, SQL);
388  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__)) {
389  return -1;
390  }
391  if (PQntuples(result)) {
392  strcpy(uploadtree_tablename, PQgetvalue(result, 0, 0));
393  PQclear(result);
394  }
395 
396  printfInCaseOfVerbosity("Deleting local license decisions for upload %ld\n",
397  uploadId);
398  /* delete from clearing_event table. */
399  snprintf(SQL, MAXSQL, "WITH alld AS ("
400  "SELECT *, ROW_NUMBER() OVER "
401  "(PARTITION BY clearing_event_pk ORDER BY scope DESC) rnum "
402  "FROM clearing_event ce "
403  "INNER JOIN clearing_decision_event cde "
404  "ON cde.clearing_event_fk = ce.clearing_event_pk "
405  "INNER JOIN clearing_decision cd "
406  "ON cd.clearing_decision_pk = cde.clearing_decision_fk "
407  "AND cd.uploadtree_fk IN "
408  "(SELECT uploadtree_pk FROM %s WHERE upload_fk = %ld)) "
409  "DELETE FROM clearing_event ce USING alld AS ad "
410  "WHERE ad.rnum = 1 AND ad.scope = 0 " // Make sure not to delete global decisions
411  "AND ce.clearing_event_pk = ad.clearing_event_pk;",
412  uploadtree_tablename, uploadId);
413  PQexecCheckClear("Deleting from clearing_event", SQL, __FILE__, __LINE__);
414 
415  /* delete from clearing_decision_event table. */
416  snprintf(SQL, MAXSQL, "DELETE FROM clearing_decision_event AS cde "
417  "USING clearing_decision AS cd "
418  "WHERE cd.scope = 0 " // Make sure not to delete global decisions
419  "AND cd.uploadtree_fk IN "
420  "(SELECT uploadtree_pk FROM %s WHERE upload_fk = %ld) "
421  "AND cd.clearing_decision_pk = cde.clearing_decision_fk;",
422  uploadtree_tablename, uploadId);
423  PQexecCheckClear("Deleting from clearing_decision_event", SQL, __FILE__, __LINE__);
424 
425  /* delete from clearing_decision table. */
426  snprintf(SQL, MAXSQL, "DELETE FROM clearing_decision "
427  "WHERE scope = 0 AND uploadtree_fk IN "
428  "(SELECT uploadtree_pk FROM %s WHERE upload_fk = %ld);",
429  uploadtree_tablename, uploadId);
430  PQexecCheckClear("Deleting from clearing_decision", SQL, __FILE__, __LINE__);
431 
432  /* delete from license_ref_bulk table. */
433  snprintf(SQL, MAXSQL, "DELETE FROM license_ref_bulk "
434  "WHERE uploadtree_fk IN "
435  "(SELECT uploadtree_pk FROM %s WHERE upload_fk = %ld);",
436  uploadtree_tablename, uploadId);
437  PQexecCheckClear("Deleting from license_ref_bulk", SQL, __FILE__, __LINE__);
438 
439  /* delete from uploadtree table. */
440  snprintf(SQL, MAXSQL, "DELETE FROM %s WHERE upload_fk = %ld;",
441  uploadtree_tablename, uploadId);
442  PQexecCheckClear("Deleting from uploadtree", SQL, __FILE__, __LINE__);
443 
444  /* Delete uploadtree_nnn table */
445  if (strcasecmp(uploadtree_tablename,"uploadtree_a")) {
446  snprintf(SQL,MAXSQL,"DROP TABLE %s;", uploadtree_tablename);
447  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
448  }
449 
450  /* delete from pfile is SLOW due to constraint checking. Do it separately. */
451  snprintf(SQL,MAXSQL,"DELETE FROM pfile USING %s WHERE pfile.pfile_pk = %s.pfile_pk;",tempTable,tempTable);
452  PQexecCheckClear("Deleting from pfile", SQL, __FILE__, __LINE__);
453 
454  snprintf(SQL,MAXSQL,"DROP TABLE %s;",tempTable);
455  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
456 
457  /* Mark upload deleted in upload table */
458  snprintf(SQL,MAXSQL,"UPDATE upload SET expire_action = 'd', "
459  "expire_date = now(), pfile_fk = NULL WHERE upload_pk = %ld;", uploadId);
460  PQexecCheckClear("Marking upload as deleted", SQL, __FILE__, __LINE__);
461 
462  PQexecCheckClear(NULL, "SET statement_timeout = 120000;", __FILE__, __LINE__);
463 
464  printfInCaseOfVerbosity("Deleted upload %ld from DB, now doing repository.\n",uploadId);
465 
466  if (Test) {
467  PQexecCheckClear(NULL, "ROLLBACK;", __FILE__, __LINE__);
468  } else {
469  PQexecCheckClear(NULL, "COMMIT;", __FILE__, __LINE__);
470  }
471 
472  printfInCaseOfVerbosity("Deleted upload %ld\n",uploadId);
473 
474  return 0; /* success */
475 } /* deleteUpload() */
476 
490 int unlinkContent (long child, long parent, int mode, int userId, int userPerm)
491 {
492  int cnt, cntUpload;
493  char SQL[MAXSQL];
494  PGresult *result;
495 
496  if(mode == 1){
497  snprintf(SQL,MAXSQL,"SELECT COUNT(DISTINCT parent_fk) FROM foldercontents WHERE foldercontents_mode=%d AND child_id=%ld",mode,child);
498  }
499  else{
500  snprintf(SQL,MAXSQL,"SELECT COUNT(parent_fk) FROM foldercontents WHERE foldercontents_mode=%d AND"
501  " child_id in (SELECT upload_pk FROM folderlist WHERE pfile_fk="
502  "(SELECT pfile_fk FROM folderlist WHERE upload_pk=%ld limit 1))",
503  mode,child);
504  }
505  result = PQexec(pgConn, SQL);
506  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
507  {
508  return -1;
509  }
510  cnt = atoi(PQgetvalue(result,0,0));
511  PQclear(result);
512  if(cnt>1 && !Test)
513  {
514  if(mode == 2){
515  snprintf(SQL,MAXSQL,"SELECT COUNT(DISTINCT parent_fk) FROM foldercontents WHERE foldercontents_mode=1 AND child_id=%ld",parent);
516  result = PQexec(pgConn, SQL);
517  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
518  {
519  return -1;
520  }
521  cntUpload = atoi(PQgetvalue(result,0,0));
522  PQclear(result);
523  if(cntUpload > 1){ // check for copied/duplicate folder
524  return 0;
525  }
526  }
527  snprintf(SQL,MAXSQL,"DELETE FROM foldercontents WHERE foldercontents_mode=%d AND child_id =%ld AND parent_fk=%ld",mode,child,parent);
528  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
529  return 0;
530  }
531  return 1;
532 }
533 
552 int listFoldersRecurse (long Parent, int Depth, long Row, int DelFlag, int userId, int userPerm)
553 {
554  int r, i, rc, maxRow;
555  int count, resultUploadCount;
556  long Fid;
557  char *Desc;
558  char SQL[MAXSQL], SQLUpload[MAXSQL];
559  char SQLFolder[MAXSQLFolder];
560  PGresult *result, *resultUpload, *resultFolder;
561 
562  rc = check_write_permission_folder(Parent, userId, userPerm);
563  if(rc < 0)
564  {
565  return rc;
566  }
567  if(DelFlag && rc > 0){
568  return 1;
569  }
570 
571  snprintf(SQLFolder, MAXSQLFolder,"SELECT COUNT(*) FROM folderlist WHERE folder_pk=%ld",Parent);
572  resultFolder = PQexec(pgConn, SQLFolder);
573  count= atoi(PQgetvalue(resultFolder,0,0));
574  PQclear(resultFolder);
575 
576  /* Find all folders with this parent and recurse, but don't show uploads, if they also exist in other directories */
577  snprintf(SQL,MAXSQL,"SELECT folder_pk,foldercontents_mode,name,description,upload_pk,pfile_fk FROM folderlist WHERE parent=%ld"
578  " ORDER BY name,parent,folder_pk ", Parent);
579  result = PQexec(pgConn, SQL);
580  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
581  {
582  return -1;
583  }
584  maxRow = PQntuples(result);
585  for(r=0; r < maxRow; r++)
586  {
587  if (atol(PQgetvalue(result,r,0)) == Parent)
588  {
589  continue;
590  }
591 
592  Fid = atol(PQgetvalue(result,r,0));
593  if (Fid != 0)
594  {
595  if (!DelFlag)
596  {
597  for(i=0; i<Depth; i++)
598  {
599  fputs(" ",stdout);
600  }
601  printf("%4ld :: %s",Fid,PQgetvalue(result,r,2));
602  Desc = PQgetvalue(result,r,3);
603  if (Desc && Desc[0])
604  {
605  printf(" (%s)",Desc);
606  }
607  printf("\n");
608  }
609  rc = listFoldersRecurse(Fid,Depth+1,Parent,DelFlag,userId,userPerm);
610  if (rc < 0)
611  {
612  if (DelFlag)
613  {
614  printf("Deleting the folder failed.");
615  }
616  return 1;
617  }
618  }
619  else
620  {
621  if (DelFlag==1 && unlinkContent(Parent,Row,1,userId,userPerm)==0)
622  {
623  continue;
624  }
625  if (rc < 0)
626  {
627  return rc;
628  }
629  if (DelFlag)
630  {
631  snprintf(SQLUpload, MAXSQL,"SELECT COUNT(*) FROM folderlist WHERE pfile_fk=%ld", atol(PQgetvalue(result,r,5)));
632  resultUpload = PQexec(pgConn, SQLUpload);
633  resultUploadCount = atoi(PQgetvalue(resultUpload,0,0));
634  if(count < 2 && resultUploadCount < 2)
635  {
636  rc = deleteUpload(atol(PQgetvalue(result,r,4)),userId, userPerm);
637  if (rc < 0)
638  {
639  return rc;
640  }
641  if (rc != 0)
642  {
643  printf("Deleting the folder failed since it contains uploads you can't delete.");
644  return rc;
645  }
646  }
647  else{
648  rc = unlinkContent(atol(PQgetvalue(result,r,4)),Parent,2,userId,userPerm);
649  if(rc < 0){
650  return rc;
651  }
652  }
653  }
654  else
655  {
656  rc = check_read_permission_upload(atol(PQgetvalue(result,r,4)),userId,userPerm);
657  if (rc < 0)
658  {
659  return rc;
660  }
661  if (rc == 0)
662  {
663  for(i=0; i<Depth; i++)
664  {
665  fputs(" ",stdout);
666  }
667  printf("%4s :: Contains: %s\n","--",PQgetvalue(result,r,2));
668  }
669  }
670  }
671  }
672  PQclear(result);
673 
674  switch(Parent)
675  {
676  case 1: /* skip default parent */
677  if (DelFlag != 0)
678  {
679  printf("INFO: Default folder not deleted.\n");
680  }
681  break;
682  case 0: /* it's an upload */
683  break;
684  default: /* it's a folder */
685  if (DelFlag == 0)
686  {
687  break;
688  }
689  printf("INFO: folder id=%ld will be deleted with flag %d\n",Parent,DelFlag);
690  if (DelFlag==1)
691  {
692  rc = unlinkContent(Parent,Row,1,userId,userPerm);
693  if (rc == 0)
694  {
695  break;
696  }
697  if (rc < 0)
698  {
699  return rc;
700  }
701  }
702  if(Row > 0)
703  snprintf(SQL,MAXSQL,"DELETE FROM foldercontents WHERE foldercontents_mode=1 AND parent_fk=%ld AND child_id=%ld",Row,Parent);
704  else
705  snprintf(SQL,MAXSQL,"DELETE FROM foldercontents WHERE foldercontents_mode=1 AND child_id=%ld",Parent);
706  if (Test)
707  {
708  printf("TEST: %s\n",SQL);
709  }
710  else
711  {
712  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
713  }
714  if(Row > 0)
715  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);
716  else
717  snprintf(SQL,MAXSQL,"DELETE FROM folder WHERE folder_pk = '%ld';",Parent);
718  if (Test)
719  {
720  printf("TEST: %s\n",SQL);
721  }
722  else
723  {
724  PQexecCheckClear(NULL, SQL, __FILE__, __LINE__);
725  }
726  } /* switch() */
727 
728  return 0; /* success */
729 } /* listFoldersRecurse() */
730 
740 int listFoldersFindDetatchedFolders(PGresult *result, int userId, int userPerm)
741 {
742  int DetachFlag=0;
743  int i,j;
744  int maxRow = PQntuples(result);
745  long Fid; /* folder ids */
746  int Match;
747  char *Desc;
748  int rc;
749 
750  /* Find detached folders */
751  for(i=0; i < maxRow; i++)
752  {
753  Fid = atol(PQgetvalue(result,i,1));
754  if (Fid == 1)
755  {
756  continue; /* skip default parent */
757  }
758  Match=0;
759  for(j=0; (j<maxRow) && !Match; j++)
760  {
761  if ((i!=j) && (atol(PQgetvalue(result,j,0)) == Fid)) Match=1;
762  }
763  if (!Match && !atol(PQgetvalue(result,i,4)))
764  {
765  if (!DetachFlag)
766  {
767  printf("# Unlinked folders\n");
768  DetachFlag=1;
769  }
770  printf("%4ld :: %s",Fid,PQgetvalue(result,i,2));
771  Desc = PQgetvalue(result,i,3);
772  if (Desc && Desc[0])
773  {
774  printf(" (%s)",Desc);
775  }
776  printf("\n");
777  rc = listFoldersRecurse(Fid,1,i,0,userId,userPerm);
778  if (rc < 0)
779  {
780  return rc;
781  }
782  }
783  }
784  return 0;
785 }
786 
794 int listFoldersFindDetatchedUploads(PGresult *result, int userId, int userPerm)
795 {
796  int DetachFlag=0;
797  int i,j;
798  int maxRow = PQntuples(result);
799  long Fid; /* folder ids */
800  int Match;
801  char *Desc;
802  /* Find detached uploads */
803  for(i=0; i < maxRow; i++)
804  {
805  Fid = atol(PQgetvalue(result,i,1));
806  if (Fid == 1)
807  {
808  continue; /* skip default parent */
809  }
810  Match=0;
811  for(j=0; (j<maxRow) && !Match; j++)
812  {
813  if ((i!=j) && (atol(PQgetvalue(result,j,0)) == Fid)) Match=1;
814  }
815  if (!Match && atol(PQgetvalue(result,i,4)))
816  {
817  if (!DetachFlag)
818  {
819  printf("# Unlinked uploads (uploads without folders)\n");
820  DetachFlag=1;
821  }
822  printf("%4s",PQgetvalue(result,i,4));
823  printf(" :: %s",PQgetvalue(result,i,2));
824  Desc = PQgetvalue(result,i,3);
825  if (Desc && Desc[0])
826  {
827  printf(" (%s)",Desc);
828  }
829  printf("\n");
830  }
831  }
832  return 0;
833 }
834 
843 int listFoldersFindDetatched(int userId, int userPerm)
844 {
845  char SQL[MAXSQL];
846  PGresult *result;
847  int rc;
848 
849  snprintf(SQL,MAXSQL,"SELECT folder_pk,parent,name,description,upload_pk FROM folderlist ORDER BY name,parent,folder_pk;");
850  result = PQexec(pgConn, SQL);
851  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
852  {
853  return -1;
854  }
855  rc = listFoldersFindDetatchedFolders(result, userId, userPerm);
856  if (rc < 0 )
857  {
858  PQclear(result);
859  return rc;
860  }
861  rc = listFoldersFindDetatchedUploads(result, userId, userPerm);
862  PQclear(result);
863  if (rc < 0 )
864  {
865  return rc;
866  }
867  return 0;
868 }
869 
875 int listFolders (int userId, int userPerm)
876 {
877  char SQL[MAXSQL];
878  PGresult *result;
879  int rc;
880 
881  if(userPerm == 0){
882  printf("you do not have the permsssion to view the folder list.\n");
883  return 1;
884  }
885 
886  printf("# Folders\n");
887  snprintf(SQL,MAXSQL,"SELECT folder_name from folder where folder_pk =1;");
888  result = PQexec(pgConn, SQL);
889  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
890  {
891  return -1;
892  }
893 
894  printf("%4d :: %s\n", 1, PQgetvalue(result,0,0));
895  PQclear(result);
896 
897  rc = listFoldersRecurse(1,1,-1,0,userId,userPerm);
898  if (rc < 0)
899  {
900  return rc;
901  }
902 
903  rc = listFoldersFindDetatched(userId, userPerm);
904  if (rc < 0)
905  {
906  return rc;
907  }
908  return 0;
909 } /* listFolders() */
910 
918 int listUploads (int userId, int userPerm)
919 {
920  int Row,maxRow;
921  long NewPid;
922  PGresult *result;
923  int rc;
924  char *SQL = "SELECT upload_pk,upload_desc,upload_filename FROM upload ORDER BY upload_pk;";
925  printf("# Uploads\n");
926  result = PQexec(pgConn, SQL);
927  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__))
928  {
929  exitNow(-1);
930  }
931 
932  /* list each value */
933  maxRow = PQntuples(result);
934  for(Row=0; Row < maxRow; Row++)
935  {
936  NewPid = atol(PQgetvalue(result,Row,0));
937  rc = check_read_permission_upload(NewPid, userId, userPerm);
938  if (rc < 0)
939  {
940  PQclear(result);
941  return rc;
942  }
943  if (NewPid >= 0 && (userPerm == PERM_ADMIN || rc == 0))
944  {
945  char *S;
946  printf("%ld :: %s",NewPid,PQgetvalue(result,Row,2));
947  S = PQgetvalue(result,Row,1);
948  if (S && S[0]) printf(" (%s)",S);
949  printf("\n");
950  }
951  }
952  PQclear(result);
953  return 0;
954 } /* listUploads() */
955 
972 int deleteFolder(long cFolder, long pFolder, int userId, int userPerm)
973 {
974  if(pFolder == 0) pFolder= -1 ;
975  return listFoldersRecurse(cFolder, 0,pFolder,2,userId,userPerm);
976 } /* deleteFolder() */
977 
978 /**********************************************************************/
979 
996 int readAndProcessParameter (char *Parm, int userId, int userPerm)
997 {
998  char *L;
999  int rc=0; /* assume no data */
1000  int Type=0; /* 0=undefined; 1=delete; 2=list */
1001  int Target=0; /* 0=undefined; 1=upload; 2=license; 3=folder */
1002  const char s[2] = " ";
1003  char *token;
1004  char a[15];
1005  long fd[2];
1006  int i = 0, len = 0;
1007 
1008  if (!Parm)
1009  {
1010  return(-1);
1011  }
1012  if (Verbose > 1) fprintf(stderr,"DEBUG: Line='%s'\n",Parm);
1013 
1014  /* process the string. */
1015  L = Parm;
1016  while(isspace(L[0])) L++;
1017 
1019  if (!strncasecmp(L,"DELETE",6) && isspace(L[6]))
1020  {
1021  Type=1; /* delete */
1022  L+=6;
1023  }
1024  else if (!strncasecmp(L,"LIST",4) && isspace(L[4]))
1025  {
1026  Type=2; /* list */
1027  L+=4;
1028  }
1029  while(isspace(L[0])) L++;
1031  if (!strncasecmp(L,"UPLOAD",6) && (isspace(L[6]) || !L[6]))
1032  {
1033  Target=1; /* upload */
1034  L+=6;
1035  }
1036  else if (!strncasecmp(L,"LICENSE",7) && (isspace(L[7]) || !L[7]))
1037  {
1038  Target=2; /* license */
1039  L+=7;
1040  }
1041  else if (!strncasecmp(L,"FOLDER",6) && (isspace(L[6]) || !L[6]))
1042  {
1043  Target=3; /* folder */
1044  L+=6;
1045  }
1046 
1047  len = strlen(L);
1048  memcpy(a, L,len);
1049  token = strtok(a, s);
1050 
1051  while( token != NULL )
1052  {
1053  fd[i] = atol(token);
1054  token = strtok(NULL, s);
1055  i++;
1056  }
1057 
1058  /* Handle the request */
1059  if ((Type==1) && (Target==1))
1060  {
1061  rc = deleteUpload(fd[0], userId, userPerm);
1062  }
1063  else if ((Type==1) && (Target==3))
1064  {
1065  rc = deleteFolder(fd[1],fd[0], userId, userPerm);
1066  }
1067  else if (((Type==2) && (Target==1)) || ((Type==2) && (Target==2)))
1068  {
1069  rc = listUploads(0, PERM_ADMIN);
1070  }
1071  else if ((Type==2) && (Target==3))
1072  {
1073  rc = listFolders(userId, userPerm);
1074  }
1075  else
1076  {
1077  LOG_ERROR("Unknown command: '%s'\n",Parm);
1078  }
1079 
1080  return rc;
1081 } /* readAndProcessParameter() */
1082 
1093 {
1094  char *Parm = NULL;
1095  char SQL[MAXSQL];
1096  PGresult *result;
1097  int userId = -1;
1098  int userPerm = -1;
1099 
1100  while(fo_scheduler_next())
1101  {
1102  Parm = fo_scheduler_current();
1103  userId = fo_scheduler_userID();
1104 
1105  /* get perm level of user */
1106  snprintf(SQL,MAXSQL,"SELECT user_perm FROM users WHERE user_pk='%d';", userId);
1107  result = PQexec(pgConn, SQL);
1108  if (fo_checkPQresult(pgConn, result, SQL, __FILE__, __LINE__) || !PQntuples(result))
1109  {
1110  exitNow(0);
1111  }
1112  userPerm = atoi(PQgetvalue(result, 0, 0));
1113  PQclear(result);
1114 
1115  int returnCode = readAndProcessParameter(Parm, userId, userPerm);
1116  if (returnCode != 0)
1117  {
1118  /* Loglevel is to high, but scheduler expects FATAL log message before exit */
1119  LOG_FATAL("Due to permission problems, the delagent was not able to list or delete the requested objects or they did not exist.");
1120  exitNow(returnCode);
1121  }
1122  }
1123 }
1131 void exitNow(int exitVal)
1132 {
1133  if (pgConn) PQfinish(pgConn);
1134 
1135  if (exitVal) LOG_ERROR("Exiting with status %d", exitVal);
1136 
1137  fo_scheduler_disconnect(exitVal);
1138  exit(exitVal);
1139 } /* exitNow() */
char SQL[256]
SQL query to execute.
Definition: adj2nest.c:78
char * uploadtree_tablename
upload.uploadtree_tablename
Definition: adj2nest.c:100
int listFoldersFindDetatchedUploads(PGresult *result, int userId, int userPerm)
Given a PGresult, find detached uploads.
Definition: util.c:794
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:165
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:490
int readAndProcessParameter(char *Parm, int userId, int userPerm)
Parse parameters.
Definition: util.c:996
void doSchedulerTasks()
process the jobs from scheduler
Definition: util.c:1092
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:228
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:263
int listFoldersRecurse(long Parent, int Depth, long Row, int DelFlag, int userId, int userPerm)
Draw folder tree.
Definition: util.c:552
int authentication(char *user, char *password, int *userId, int *userPerm)
if this account is valid
Definition: util.c:96
PGconn * pgConn
Database connection.
Definition: util.c:21
int printfInCaseOfVerbosity(const char *format,...)
If verbose is on, print to stdout.
Definition: util.c:29
void exitNow(int exitVal)
Exit function. This does all cleanup and should be used instead of calling exit() or main() return.
Definition: util.c:1131
void PQexecCheckClear(const char *desc, char *SQL, char *file, const int line)
Execute SQL query and create the result.
Definition: util.c:77
int Verbose
Verbose level.
Definition: util.c:19
PGresult * PQexecCheck(const char *desc, char *SQL, char *file, const int line)
simple wrapper which includes PQexec and fo_checkPQcommand
Definition: util.c:52
int listUploads(int userId, int userPerm)
List every upload ID.
Definition: util.c:918
int listFoldersFindDetatched(int userId, int userPerm)
Given a user id, find detached folders and uploads.
Definition: util.c:843
int Test
Definition: util.c:20
int listFolders(int userId, int userPerm)
List every folder.
Definition: util.c:875
int deleteUpload(long uploadId, int userId, int userPerm)
Given an upload ID, delete it.
Definition: util.c:285
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:211
int deleteFolder(long cFolder, long pFolder, int userId, int userPerm)
recursively delete a folder
Definition: util.c:972
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:196
int listFoldersFindDetatchedFolders(PGresult *result, int userId, int userPerm)
Given a PGresult, find detached folders.
Definition: util.c:740
int s
The socket that the CLI will use to communicate.
Definition: fo_cli.c:37
FUNCTION int getEffectivePermissionOnUpload(PGconn *pgConn, long UploadPk, int user_pk, int user_perm)
Get users permission to this upload.
Definition: libfossagent.c:321
int fo_checkPQresult(PGconn *pgConn, PGresult *result, char *sql, char *FileID, int LineNumb)
Check the result status of a postgres SELECT.
Definition: libfossdb.c:170
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:204
#define PERM_WRITE
Read-Write permission.
Definition: libfossology.h:33
#define PERM_READ
Read-only permission.
Definition: libfossology.h:32
#define PERM_ADMIN
Administrator.
Definition: libfossology.h:34
int fo_RepExist(char *Type, char *Filename)
Determine if a file exists.
Definition: libfossrepo.c:486
int fo_RepRemove(char *Type, char *Filename)
Delete a repository file.
Definition: libfossrepo.c:568
void fo_scheduler_disconnect(int retcode)
Disconnect the scheduler connection.
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 fo_scheduler_userID()
Gets the id of the user that created the job that the agent is running.
char * fo_scheduler_current()
Get the last read string from the scheduler.
char * fo_scheduler_next()
Get the next data to process from the scheduler.
Definition: match.h:20