Does anyone know the api for adding users and groups in unix and removing them ? I want to do this programatically.
Thanks,
Frank
I started looking at some system calls and found the following. Note that they are of varying standards, so not all may work on your Unix version:
getpwent
setpwent
putpwent
These however, all assume a password file. Out of curiosity, I straced useradd to find out what he did. Here's a small section of it's output:
# grep -E 'passwd|shadow' useradd.log.20283
...
open("/etc/shadow", O_RDONLY|O_CLOEXEC) = 3
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
open("/etc/passwd.20283", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
link("/etc/passwd.20283", "/etc/passwd.lock") = 0
stat("/etc/passwd.20283", {st_mode=S_IFREG|0600, st_size=6, ...}) = 0
unlink("/etc/passwd.20283") = 0
open("/etc/passwd", O_RDWR) = 4
open("/etc/shadow.20283", O_WRONLY|O_CREAT|O_EXCL, 0600) = 5
link("/etc/shadow.20283", "/etc/shadow.lock") = 0
stat("/etc/shadow.20283", {st_mode=S_IFREG|0600, st_size=6, ...}) = 0
unlink("/etc/shadow.20283") = 0
open("/etc/shadow", O_RDWR) = 5
open("/etc/gshadow.20283", O_WRONLY|O_CREAT|O_EXCL, 0600) = 7
link("/etc/gshadow.20283", "/etc/gshadow.lock") = 0
stat("/etc/gshadow.20283", {st_mode=S_IFREG|0600, st_size=6, ...}) = 0
unlink("/etc/gshadow.20283") = 0
open("/etc/gshadow", O_RDWR) = 7
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 8
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 9
open("/etc/passwd-", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 9
utime("/etc/passwd-", [2010/09/02-07:07:34, 2010/09/02-07:07:34]) = 0
open("/etc/passwd+", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
lstat("/etc/passwd", {st_mode=S_IFREG|0644, st_size=2479, ...}) = 0
rename("/etc/passwd+", "/etc/passwd") = 0
open("/etc/shadow-", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
utime("/etc/shadow-", [2010/09/02-07:07:34, 2010/09/02-07:07:34]) = 0
open("/etc/shadow+", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
lstat("/etc/shadow", {st_mode=S_IFREG|0600, st_size=1429, ...}) = 0
r ename("/etc/shadow+", "/etc/shadow") = 0
open("/etc/gshadow-", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
utime("/etc/gshadow-", [2010/09/02-07:07:34, 2010/09/02-07:07:34]) = 0
open("/etc/gshadow+", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
lstat("/etc/gshadow", {st_mode=S_IFREG|0400, st_size=1069, ...}) = 0
rename("/etc/gshadow+", "/etc/gshadow") = 0
unlink("/etc/shadow.lock") = 0
unlink("/etc/passwd.lock") = 0
unlink("/etc/gshadow.lock") = 0
Although you get a better idea what's going on with the full context, note that it links a temporary file it created (/etc/passwd.20283) to /etc/passwd.lock. useradd does similarly with the shadow, and gshadow files as well.
It's also important to note that useradd made four calls out to nscd. Two of these were for passwd, and two were for group:
execve("/usr/sbin/nscd", ["/usr/sbin/nscd", "nscd", "-i", "passwd"], [/* 0 vars */]) = 0
If there isn't an API (and I can't seem to find one), it may be because there's many more ways to store users than simple passwd files. Indeed, it's possible that the machine has no control at all over the users.
EDIT: I suppose it's also important to note that useradd consulted /etc/nsswitch.conf as well, likely to verify the origin of the user database. Furthermore, userdel behaved almost identically, creating similarly named temporary and lock files.
I tested under Linux using the following command:
strace -o useradd.log -f -ff -s 1024 useradd tempuser
strace may also appear as truss and ktrace on other unix systems.
I found this question while looking for a way to list all groups on a Unix.
But to create and delete users you can programatically call the utility programs useradd, userdel, groupadd, groupdel since you would know the user name been sent. But I guess you will need superuser rights to invoke them. Anyway you can check the process exit code for command status.
useradd xxx // status zero operation completed
useradd xxx // status nine user already exists
Hope it helps.
Related
When I run the following command, I get the expected output but the program does not terminate immediately.
$ mpirun -np 2 echo 1
1
1
The program does not respond to interrupts either. Only after a minute or so I get back to the shell.
Or differently put: the program mpirun -np 2 echo 1; echo 'done' runs successfully but takes forever.
Update:
I ran strace mpirun -np 2 echo 1
The program hangs here:
sysinfo({uptime=5064793, loads=[153856, 184128, 229600], totalram=67362279424, freeram=26006364160, sharedram=8040448, bufferram=1739857920, totalswap=34359734272, freeswap=34358018048, procs=309, totalhigh=0, freehigh=0, mem_unit=1}) = 0
uname({sysname="Linux", nodename="euler", ...}) = 0
ioctl(13, _IOC(0, 0, 0x25, 0)
and then here:
openat(AT_FDCWD, "/tmp/openmpi-sessions-216211#euler_0/42701", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = -1 ENOENT (No such file or directory)
munmap(0x7f61ed88c000, 2127408) = 0
munmap(0x7f61ee0a1000, 2101720) = 0
close(9) = 0
munmap(0x7f61ede9e000, 2105664) = 0
munmap(0x7f61ed685000, 2122480) = 0
munmap(0x7f61eda95000, 2109856) = 0
munmap(0x7f61ed47c000, 2130304) = 0
munmap(0x7f61ed05b000, 2109896) = 0
munmap(0x7f61ecc9a000, 3934648) = 0
munmap(0x7f61ed25f000, 2212016) = 0
munmap(0x7f61ec8e3000, 3894144) = 0
munmap(0x7f61ec6bd000, 2248968) = 0
munmap(0x7f61ea776000, 28999696) = 0
munmap(0x7f61edc99000, 2110072) = 0
exit_group(0) = ?
Could you help me debug this further?
Apparently, the NVIDIA driver was broken. Updating the driver to 440.64.00 resolved the issue.
I am trying to run the following command in ubuntu terminal
patch -p0 -i adjustmentFile.patch
That is giving the following error
patching file ./src/helpStructures/CastaliaModule.cc
patching file ./src/node/communication/mac/tunableMac/TunableMAC.cc
Hunk #2 FAILED at 456.
1 out of 2 hunks FAILED -- saving rejects to file ./src/node/communication/mac/tunableMac/TunableMAC.cc.rej
I tried almost all the ways suggested in the link Hunk #1 FAILED at 1. What's that mean?. However, nothing worked.
Here is my version detail
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Jun 06 2019 17:31:41)
Included patches: 1-1453
The patch file:
diff -r -u ./src/helpStructures/CastaliaModule.cc ./src/helpStructures/CastaliaModule.cc
--- ./src/helpStructures/CastaliaModule.cc 2010-12-09 09:56:47.000000000 -0300
+++ ./src/helpStructures/CastaliaModule.cc 2011-12-20 00:16:39.944320051 -0300
## -180,6 +180,8 ##
classPointers.resourceManager = getParentModule()->getParentModule()->getSubmodule("ResourceManager");
else if (name.compare("SensorManager") == 0)
classPointers.resourceManager = getParentModule()->getSubmodule("ResourceManager");
+ else if (name.compare("Routing") == 0)
+ classPointers.resourceManager = getParentModule()->getParentModule()->getSubmodule("ResourceManager");
else
opp_error("%s module has no rights to call drawPower() function", getFullPath().c_str());
if (!classPointers.resourceManager)
Only in ./src/helpStructures: CastaliaModule.cc~
diff -r -u ./src/node/communication/mac/tunableMac/TunableMAC.cc ./src/node/communication/mac/tunableMac/TunableMAC.cc
--- ./src/node/communication/mac/tunableMac/TunableMAC.cc 2011-03-30 02:14:34.000000000 -0300
+++ ./src/node/communication/mac/tunableMac/TunableMAC.cc 2011-12-19 23:57:43.894686687 -0300
## -405,6 +405,8 ##
void TunableMAC::fromRadioLayer(cPacket * pkt, double rssi, double lqi)
{
TunableMacPacket *macFrame = dynamic_cast <TunableMacPacket*>(pkt);
+ macFrame->getMacRadioInfoExchange().RSSI = rssi;
+ macFrame->getMacRadioInfoExchange().LQI = lqi;
if (macFrame == NULL){
collectOutput("TunableMAC packet breakdown", "filtered, other MAC");
return;
## -454,7 +456,8 ##
}
case DATA_FRAME:{
- toNetworkLayer(macFrame->decapsulate());
+ cPacket *netPkt = decapsulatePacket(macFrame);
+ toNetworkLayer(netPkt);
collectOutput("TunableMAC packet breakdown", "received data pkts");
if (macState == MAC_STATE_RX) {
cancelTimer(ATTEMPT_TX);
Only in ./src/node/communication/mac/tunableMac: TunableMAC.cc~
Patching takes some changes made to a file X, and applies them to a different instance of file X. That is, suppose you start with generation 1 of file X; you make changes to get generation 2-a, and someone else starts with generation 1 to make generation 2-b. Now you want to take his edits that created his generation 2-b, and apply them to your generation 2-a.
If 'his' changes clash with 'your' changes, they cannot be automatically patched.
You'll need to look at the changes being made in hunk 2.
- toNetworkLayer(macFrame->decapsulate());
+ cPacket *netPkt = decapsulatePacket(macFrame);
+ toNetworkLayer(netPkt);
and figure out what you want the result to look like. Someone needs to know what the result is supposed to be. You can't resolve conflicts without knowledge of intent.
I'm developing a program using Android Studio that runs as expected when the normal APK is run, but if I compile it for Debugging, it crashes before the 1st line of code executes, so setting a brake-point on the 1st line of my code to execute, never trips.
I have already
Completely deleted the program from the test target (nexus 7)
Power offed the tablet and then restarted tablet
Power off/rebooted the development machine
Cleaned the project
Rebuilt the project.
The program still runs as expected when compiled/run without debugging.
Crashes after loading, but before running when compiled/run in debug.
Any ideas on how to try and overcome this problem would be welcome.
Android Studio 2.1.2
compileSdkVersion 21
buildToolsVersion "21.1.2
Copy of exception variable after crash
shadow$klass = {Class#613} "class java.lang.Class"
superClass = {Class#1356} "class java.lang.Exception"
2 = {ArtMethod#3613}
17 = {ArtMethod#3628}
numReferenceStaticFields = 0
verifyErrorClass = null
iFields = {ArtField[2]#3636}
stackState = {Object[22]#3602}
3 = {ArtMethod#3614}
0 = {ArtMethod#3611}
errno = 2
classLoader = null
8 = {ArtMethod#3619}
dexCache = {DexCache#3633}
functionName = "stat"
virtualMethods = {ArtMethod[3]#3639}
shadow$monitor = -1294973706
primitiveType = 0
Exception = {ErrnoException#3590}
16 = {ArtMethod#3627}
value = {char[4]#3607}
ifTable = {Object[2]#3637}
vtable = null
4 = {ArtMethod#3615}
suppressedExceptions = {Collections$EmptyList#3604} size = 0
classSize = 468
functionName = "stat"
6 = {ArtMethod#3617}
errno = 2
hashCode = 3540564
referenceStaticOffsets = 0
1 = {ArtMethod#3612}
13 = {ArtMethod#3624}
detailMessage = null
18 = {ArtMethod#3629}
stackTrace = {StackTraceElement[0]#3603}
sFields = null
dexClassDefIndex = 4
componentType = null
15 = {ArtMethod#3626}
status = 10
10 = {ArtMethod#3621}
shadow$klass = {Class#3428} "class java.lang.String"
shadow$klass = {Class#183} "class android.system.ErrnoException"
19 = {ArtMethod#3630}
12 = {ArtMethod#3623}
5 = {ArtMethod#3616}
referenceInstanceOffsets = -1090519040
cause = {ErrnoException#3590} "android.system.ErrnoException: stat failed: ENOENT (No such file or directory)"
suppressedExceptions = {Collections$EmptyList#3604} size = 0
objectSize = 36
detailMessage = null
shadow$klass = {Class#183} "class android.system.ErrnoException"
dexCacheStrings = {String[23663]#3634}
dexTypeIndex = 6
shadow$monitor = -1665173294
offset = 0
14 = {ArtMethod#3625}
numReferenceInstanceFields = 1
Variables debug info not available
21 = {int[21]#3632}
name = "android.system.ErrnoException"
stackState = {Object[22]#3602}
clinitThreadId = 456
directMethods = {ArtMethod[2]#3635}
7 = {ArtMethod#3618}
20 = {ArtMethod#3631}
9 = {ArtMethod#3620}
11 = {ArtMethod#3622}
count = 4
shadow$monitor = -1353303322
cause = {ErrnoException#3590} "android.system.ErrnoException: stat failed:
ENOENT (No such file or directory)"
stackTrace = {StackTraceElement[0]#3603}
accessFlags = 524305
Well, I solved the problem myself. NOT in a way that I'd like to have solved it, or that in any way explained what caused the problem, but the problem was corrected. - I've been in IT long enough to know you need to do backups, and once I remembered I had them, I pulled the backup of a day before the problem surfaced, restored the entire directory tree when the project resided and PUFF, everything worked. Re-applied any code changes I made in the day after the backup (I keep pretty good paper notes on changes) and away I went.
- BUT -
This doesn't explain why the system was working one day and after a night of sleep, the system wouldn't work the next day. And I still have no idea how a person who received the error message I received would go about debugging/fixing the problem if he/she didn't have a good set of backups.
ALSO – it seems that someone downgraded my question. Maybe it did deserve to be downgraded, but I have no idea why it was downgraded. The question seemed reasonable to me. One day late in the evening the system worked, and the next day it didn't and the information the system offered was posted in the question.
I'd be very happy if anyone could explain to me how a person could extract information from the posted log, to find out what was wrong – or – at least explain why the question was improper enough to warrant a downgrade ?
any reasonable comments would be welcome.
Joe Cullity
I try to show tail of a text file. If file is small, there is no difference. However if file is too big (~5 gB), tailf does not respond. On the other hand tail -f works fine. What is difference between them?
I have faced the same issue. The log file was about 47GB. The tailf just waits almost infinite. But the tail -f begin to print the output within seconds.
I have digged deeper by examining the underlying system calls using strace command. The results given below:
# strace tailf /var/log/messages
(truncated)
stat("/var/log/messages", {st_mode=S_IFREG|0600, st_size=47432599401, ...}) = 0
open("/var/log/messages", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0600, st_size=47432600425, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7dba2d1000
read(3, "Nov 1 03:23:01 hostnameXXXX"..., 4096) = 4096
read(3, "0.31.148.12)\nNov 1 03:54:33 del"..., 4096) = 4096
read(3, "io.c(600) [receiver=3.0.6]\nNov "..., 4096) = 4096
(truncated)
As you can see, the tailf is trying to read (buffer) all the lines from beginning before generating output to the screen.
Check the output of tail -f below, here it is using the system call lseek (C/C++) to directly jump to end of file and start reading from there:
# strace tail -f /var/log/messages
(truncated)
open("/var/log/messages", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0600, st_size=47294167448, ...}) = 0
lseek(3, 0, SEEK_CUR) = 0
lseek(3, 0, SEEK_END) = 47294170917
lseek(3, 47294169088, SEEK_SET) = 47294169088
(truncated)
From the man page:
tailf will print out the last 10 lines of a file and then wait for the
file to grow. It is similar to tail -f but does not access the file
when it is not growing. This has the side effect of not updating the
access time for the file, so a filesystem flush does not occur periodi-
cally when no log activity is happening.
http://linuxcommand.org/man_pages/tailf1.html
If it doesn't access the file directly it will have some difficulties with very lage files, depending on your machines setup.
I have a running a fuse fs with options allow_other and umask 0. This gives me a set of files with permissions set to 777. Though when I try to ls -l in the directory containing the files I get the following output:
ls: name: Operation not permitted
ls: tags: Operation not permitted
ls: location: Operation not permitted
ls: ext: Operation not permitted
ls: experiment_id: Operation not permitted
ls: file_path: Operation not permitted
Can anyone tell me why despite having global permissions (777) I am still getting operation not permitted?
On running strace, I get the following traces:
lstat("tags", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
lgetxattr("tags", "security.selinux", 0x112ae80, 255) = -1 EPERM (Operation not permitted)
write(2, "ls: ", 4ls: ) = 4
write(2, "tags", 4tags) = 4
write(2, ": Operation not permitted", 25: Operation not permitted) = 25
write(2, "\n", 1
) = 1
lstat("location", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
lgetxattr("location", "security.selinux", 0x112aea0, 255) = -1 EPERM (Operation not permitted)
write(2, "ls: ", 4ls: ) = 4
write(2, "location", 8location) = 8
write(2, ": Operation not permitted", 25: Operation not permitted) = 25
write(2, "\n", 1) = 1
lstat("ext", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
lgetxattr("ext", "security.selinux", 0x112aec0, 255) = -1 EPERM (Operation not permitted)
write(2, "ls: ", 4ls: ) = 4
write(2, "ext", 3ext) = 3
write(2, ": Operation not permitted", 25: Operation not permitted) = 25
write(2, "\n", 1) = 1
lstat("experiment_id", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
lgetxattr("experiment_id", "security.selinux", 0x112aee0, 255) = -1 EPERM (Operation not permitted)
write(2, "ls: ", 4ls: ) = 4
write(2, "experiment_id", 13experiment_id) = 13
write(2, ": Operation not permitted", 25: Operation not permitted) = 25
write(2, "\n", 1) = 1
lstat("file_path", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
lgetxattr("file_path", "security.selinux", 0x112af00, 255) = -1 EPERM (Operation not permitted)
write(2, "ls: ", 4ls: ) = 4
write(2, "file_path", 9file_path) = 9
write(2, ": Operation not permitted", 25: Operation not permitted) = 25
write(2, "\n", 1) = 1
So from the trace, it looks like its trying to get the selinux attribute even though its disabled on my system.
cat /etc//sysconfig/selinux
SELINUX=disabled
SELINUXTYPE=targeted
follow the below steps to resolve the issue. I tried below steps, worked for me
1.Pull down the Apple menu and choose ‘System Preferences’
2.Choose “Security & Privacy” control panel
3.Now select the “Privacy” tab, then from the left-side menu select “Full Disk Access”
4.Click the lock icon in the lower left corner of the preference panel and authenticate with an admin level login
5.Now click the [+] plus button to add an application with full disk access
6.Navigate to the /Applications/Utilities/ folder and choose “Terminal” to grant Terminal with Full Disk Access privileges
7.Relaunch Terminal, the “Operation not permitted” error messages will be gone
Set permissions on the directory that contains the files.
Use strace(1) at least as
strace ls -l
this will show you all the syscalls done by ls and you would recognize which FUSE file-system related syscalls(2) are failing.
Perhaps stat(2) is failing on individual directory entries like tags etc...?
You are probably forgetting to implement some operations in your FUSE.
The problem was with my getxattr implementation. I was returning -1 on error which translated to EPERM, instead I should have returned ENODATA which is more correct error case for my logic. This fixed those errors as well.
https://gowalker.org/github.com/hanwen/go-fuse/fuse