PAM standard macros and logging on CentOS7 - c

According to the D(x) macro defined in pam_macros.h (source code) and used as follows:
D(("Hello PAM World"));
Where is this log located on CentOS7?
Note that I am using as flag debug in my pam.d conf file.
I tried also the following command:
grep -rnw '/var/log/' -e "Hello Pam World"
But with no success.

In the file you link, there are these lines at the top:
/*
* This is for debugging purposes ONLY. DO NOT use on live systems !!!
* You have been warned :-) - CG
*
* to get automated debugging to the log file, it must be created manually.
* _PAM_LOGFILE must exist, mode 666
*/
#ifndef _PAM_LOGFILE
#define _PAM_LOGFILE "/tmp/pam-debug.log"
#endif
So it looks like the output will be directed to /tmp/pam-debug.log, but you have to create it before, and give it full read-write permissions:
$ touch /tmp/pam-debug.log
$ chmod 666 /tmp/pam-debug.log
Looking to the Linux version of this file, it looks like it is written to /var/run/pam-debug.log, but only if it is compiled with PAM_DEBUG.
There a nice comment in configure.ac:
if test x"$enable_debug" = x"yes" ; then
AC_DEFINE([PAM_DEBUG],,
[lots of stuff gets written to /var/run/pam-debug.log])

Related

How to force fuzzing yield coverage data?

I'm using AFL++ 4.0c to fuzz my app. It basically wraps clang compiler too instrument my code with fuzzing shenanigans. As well I provide coverage flags:
--coverage -g -fprofile-instr-generate -fcoverage-mapping
Then I try to launch my app with fuzzer
env PARAM=paramstuff \ # setup some env
afl-fuzz -x dicts/dicts -f file.txt \ # setup afl flags
-i input -o output \ # input and output for afl
-- \
./myapp --flag --flag2 --flag3 # flags for my app
It fuzzes just fine, but coverage profile is written empty.
If some of my configuration is off and fuzzer fails to properly start the profile generated by coverage is not empty as well as .gcda output. How to allow fuzzer to trigger dump coverage as well?
if I launch my app with params profile also generated
Fuzzer works until stopped via CTRL+C. App stops the same way.
In my case AFL used fork server to fuzz parts of my app:
#ifdef __AFL_HAVE_MANUAL_CONTROL
SSH_TRACE(0, ("AFL INIT"));
__AFL_INIT();
while (__AFL_LOOP(1000)) {
#endif
/*
* regular code to fuzz goes here
*/
#ifdef __AFL_HAVE_MANUAL_CONTROL
}
#endif
So proper finalization never triggered and coverage data never dumped to profile.raw. So to force it to dump data manually I called __llvm_profile_write_file(); right after closing bracket of afl loop in the last #ifndef section. For gcc instrumentation exist similar function __gcov_flush().
Couple notes for those who fuzz things:
Don't put dump function inside fuzzing loop - it will drastically slow fuzzing performance and your profile will grow very rapidly. One such loop was able to spam about 1 GiB to profile. It probably will exhaust your disc space before you receive proper fuzzing results.
Put dump function into #ifndef guards otherwise it will mess up with regular coverage dump when you just run app. Unless you close your forked processes with __exit() and know what you are doing.

setuid not working, linux rhel6, simple example

This is a repost after being referred to "Calling a script from a setuid root C program - script does not run as root" for a solution
My problem is different in that I do not want to run the C program (and c-shell script called inside) as root. Rather, I want to run as the owner of the c program file.
Also, I tried with "setuid(0)" as this was the solution in the referenced post. This is reflected in the edited code below. Same results.
Also, I opened permissions up all the way this time with "chmod 7775" (just in case it was a permissions problem)
Here's the original note with edits to reflect the change to "setuid(0)"
I'm having a problem implementing an simple example that would demonstrate how setuid can be made to run a binary with the uid of the file owner of the binary. What I would eventually like to do is run a c-shell script using this technique.
I read that this will not work for shell scripts but also heard of a work-around using a C program to run a system() call that'll run the c-shell script ( e.g. system("source my.csh") ). I wrote a C program that attempts this, plus simply reports the current uid. This is what I tried...
From my current shell, I did a "su katman" to become the user of the binary I want to run as user katman.
I created a C program try.c. ...
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
setuid(0);
printf("In try.c ... sourcing katwhoami.csh...\n");
system( "source /home/me/su_experiments/katwhoami.csh");
printf("In try.c ... using straight system call...\n");
system("whoami");
return 0;
}
I "setuid(0)" as recommended by a reference to a different note. But earlier, I tried setting it to the uid of the C program's owner as obtained with "id -u".
The katwhoami.csh shell script is simply...
date
echo "In katwhoami.csh, I am "`whoami`
echo "In katwhoami.csh, I am "$USER
exit
Then I compiled the C program and set the bit...
% gcc -o try try.c
% chmod 7775 try
% ls -l try
-rwsrwsr-x 1 katman design 6784 Mar 1 11:59 try
And then I test it...
% try
In try.c ... sourcing katwhoami.csh...
Thu Mar 1 12:28:28 EST 2018
In katwhoami.csh, I am ktadmin
In katwhoami.csh, I am ktadmin
In try.c ... using straight system call...
ktadmin
...which is what I expected.
I exit to get back to the shell I started from, hoping that if I run try there, it'll tell me I'm "katman"....
% exit
% whoami
daveg
% try
In try.c ... sourcing katwhoami.csh...
Thu Mar 1 12:30:04 EST 2018
In katwhoami.csh, I am daveg
In katwhoami.csh, I am daveg
In try.c ... using straight system call...
daveg
... which is not what I was hoping for :-(
As you can probably tell, I'm new at using this.
Any help would be appreciated !
Update....
I tried a new sample program, a.c...
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fh;
setuid(1234);
system("whoami");
fh=fopen("test.file","w");
fprintf(fh,"Here I am\n");
fclose(fh);
return 0;
}
I compiled and set the bit
gcc -o a a.c
chmod 4775 a
Then I exited the "su" and ran as a user that is NOT the owner of the binary. Same result as before with regard to reported uid (the current uid), BUT, the owner of the file that the C program created ion this version was the owner of the C program !!! So that worked.
Is there something fishy about the "whoami" command? system() call ?
If I do a "system("source some.csh") does it create a new shell which assumes the original uid (not the owner of the C binary) ? Something like that ?
I really need the new uid to "stick" as far as child processes.

C script running as cron giving permission denied error

I have a .c file compiled and would like to run via a cron job but I end up getting this error:
/bin/sh: /usr/local/bin/get1Receive.c: Permission denied.
What is causing this error and how do I fix it?
Should I be running the .c file in cron or a different compiled file?
Results from /tmp/myvars
GROUPS=()
HOME=/root
HOSTNAME=capture
HOSTTYPE=x86_64
IFS='
'
LOGNAME=root
MACHTYPE=x86_64-redhat-linux-gnu
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PATH=/usr/bin:/bin
POSIXLY_CORRECT=y
PPID=11086
PS4='+ '
PWD=/root
SHELL=/bin/sh
SHELLOPTS=braceexpand:hashall:interactive-comments:posix
SHLVL=1
TERM=dumb
UID=0
USER=root
_=/bin/sh
Results from file get1Receive.c
file get1Receive.c
get1Receive.c: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
Snippet of codes.
sprintf(queryBuf1,"SELECT ipDest, macDest,portDest, sum(totalBits) FROM dataReceive WHERE timeStampID between '%s' And '%s' GROUP BY ipDest, macDest, portDest ",buff1,buff2);
printf("\nQuery receive %s",queryBuf1);
if(mysql_query(localConn, queryBuf1))
{
//fprintf(stderr, "%s\n", mysql_error(localConn));
printf("Error in first query of select %s\n",mysql_error(localConn));
exit(1);
}
localRes1 = mysql_store_result(localConn);
int num_fields = mysql_num_fields(localRes1);
printf("\nNumf of fields : %d",num_fields);
printf("\nNof of row : %lu",mysql_num_rows(localRes1));
If the output of this command:
file get1Receive1.c
shows that file name to be a valid executable that part is very unusual, but okay.
Assuming you are using biz14 (or your real username's ) crontab try this:
use the command crontab -e to create this line in your crontab:
* * * * * set > /tmp/myvars
Wait a few minutes, go back into crontab -e and delete that entry.
Use the set command from the command line to see what variables and aliases exist.
Compare that with that you see in /tmp/myvars You have to change how your C code executes by changing the variables and aliases the cron job runs with.
If you are running the cron job in someone else's crontab, then you have a bigger problem. Check file permissions on get1Receive1.c. and the directory it lives in. That other user (the one who wons the crontab) has to have permissions set on your directory and get1Receive1.c so the job can run.
Example crontab entry:
0 10 * * 1-5 /path/to/get1Receive1.c > /tmp/outputfile
Read /tmp/outputfile to see what you got. You are using printf in your code. printf only writes to the controlling terminal. There is no controlling terminal, so redirect the printf stuff to a file.
Last effort on this problem:
Check return codes on EVERYTHING. All C functions like fread(), any db function, etc. If a return code gives a fail response ( these are different for different function calls) then report the error number the line number and function - gcc provides LINE and func. Example:
printf("error on line %d in my code %s, error message =%s\n", __LINE__, __func__, [string of error message]);
If you do not check return codes you are writing very poor C code.
CHECK return codes, please, now!
Permission wise you could have two issues.
1. The 'c' file's permissions don't allow who you are running it as to run it.
2. You are running the cron with a script which doesn't have permissions.
Here's a helpful post: How to give permission for the cron job file?
The fact that you are running a 'c' file and referring to it as a script makes me think you're using C shell and not writing it as a C language program which would need to be compiled and have the generated executable run by the cron. If you're not using gcc or have never called gcc on your 'C' script then it's not C and call it C shell to avoid confusion.

statically compile an android program

i'm trying to write something into the dmesg log before /system being mounted.
my trouble is that for write into dmesg ( on android ) i need to use the android-specific stuff, not just my usually crossdev arm system.
just:
__android_log_print(ANDROID_LOG_DEBUG, "libnav", "DEBUG - custom program started");
all fine if you compile it as follow ( i make a standalone toolchain in /var/tmp/android ):
arm-linux-androideabi-gcc --sysroot /var/tmp/android/sysroot -llog -o custom_program custom_program.c
BUT the above command will build a dynamically linked executable, which will run fine if system is yet booted up.
"easy, just compile it statically!" i thought.
the android ndk comes with some libs but the liblog is only liblog.so, not liblog.a, so how can i log something in dmesg before /system beign mounted ?
thanks in advance.
Using arm-unknown-gnueabi-gcc and
fopen the /dev/kmsg and fprintf on the FILE * returned by fopen.
running the program while android is running will write into dmesg, but not if in early boot process. why?
#auselen
i yet have modified init to startup this static program:
init.rc snippet
on post-fs-data
write /dev/kmsg "launching test"
exec /data/test
all i see in dmesg is this...
<4>[ 6.336816] launching test
<6>[ 6.336902] init: command 'write' r=0
<6>[ 6.337115] init: command 'exec' r=-1
here you are the executable source code: http://pastebin.com/Hym1APWx

Where does linux store my syslog?

I wrote a simple test application to log something in a log file. I am using linux mint and after the application executes I try to view the log using this command:
tail -n 100 /var/log/messages
but the file messages does not exist neither tested or something. Below you can find my code. Maybe I am doing something wrong, the file isn't stored there or I need to enable logging in linux mint.
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
void init_log()
{
setlogmask(LOG_UPTO(LOG_NOTICE));
openlog("testd",LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
}
int main(void) {
init_log();
printf("Session started!");
syslog(LOG_NOTICE, "Session started!!");
closelog();
return EXIT_SUCCESS;
}
On my Ubuntu machine, I can see the output at /var/log/syslog.
On a RHEL/CentOS machine, the output is found in /var/log/messages.
This is controlled by the rsyslog service, so if this is disabled for some reason you may need to start it with systemctl start rsyslog.
As noted by others, your syslog() output would be logged by the /var/log/syslog file.
You can see system, user, and other logs at /var/log.
For more details: here's an interesting link.
Default log location (rhel) are
General messages:
/var/log/messages
Authentication messages:
/var/log/secure
Mail events:
/var/log/maillog
Check your /etc/syslog.conf or /etc/syslog-ng.conf (it depends on which of syslog facility you have installed)
Example:
$ cat /etc/syslog.conf
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none /var/log/messages
# The authpriv file has restricted access.
authpriv.* /var/log/secure
# Log all the mail messages in one place.
mail.* /var/log/maillog
#For a start, use this simplified approach.
*.* /var/log/messages
In addition to the accepted answer, it is useful to know the following ...
Each of those functions should have manual pages associated with them.
If you run man -k syslog (a keyword search of man pages) you will get a list of man pages that refer to, or are about syslog
$ man -k syslog
logger (1) - a shell command interface to the syslog(3) system l...
rsyslog.conf (5) - rsyslogd(8) configuration file
rsyslogd (8) - reliable and extended syslogd
syslog (2) - read and/or clear kernel message ring buffer; set c...
syslog (3) - send messages to the system logger
vsyslog (3) - send messages to the system logger
You need to understand the manual sections in order to delve further.
Here's an excerpt from the man page for man, that explains man page sections :
The table below shows the section numbers of the manual followed by
the types of pages they contain.
1 Executable programs or shell commands
2 System calls (functions provided by the kernel)
3 Library calls (functions within program libraries)
4 Special files (usually found in /dev)
5 File formats and conventions eg /etc/passwd
6 Games
7 Miscellaneous (including macro packages and convenā€
tions), e.g. man(7), groff(7)
8 System administration commands (usually only for root)
9 Kernel routines [Non standard]
To read the above run
$man man
So, if you run man 3 syslog you get a full manual page for the syslog function that you called in your code.
SYSLOG(3) Linux Programmer's Manual SYSLOG(3)
NAME
closelog, openlog, syslog, vsyslog - send messages to the system
logger
SYNOPSIS
#include <syslog.h>
void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);
#include <stdarg.h>
void vsyslog(int priority, const char *format, va_list ap);
Not a direct answer but hopefully you will find this useful.
You have to tell the system what information to log and where to put the info. Logging is configured in the /etc/rsyslog.conf file, then restart rsyslog to load the new config. The default logging rules are usually in a /etc/rsyslog.d/50-default.conf file.
syslog() generates a log message, which will be distributed by syslogd.
The file to configure syslogd is /etc/syslog.conf.
This file will tell your where the messages are logged.
How to change options in this file ?
Here you go
http://www.bo.infn.it/alice/alice-doc/mll-doc/duix/admgde/node74.html
Logging is very configurable in Linux, and you might want to look into your /etc/syslog.conf (or perhaps under /etc/rsyslog.d/). Details depend upon the logging subsystem, and the distribution.
Look also into files under /var/log/ (and perhaps run dmesg for kernel logs).
I'm running Ubuntu under WSL(Windows Subsystem for Linux) and systemctl start rsyslog didn't work for me.
So what I did is this:
$ service rsyslog start
Now syslog file will appear at /var/log/

Resources