setuid(0) gives EPERM on Mac OS X 10.9 - macos

when executing this:
err = setuid(0);
if (err < 0) {
fprintf(stderr, "return value: %d \n", err);
fprintf(stderr, "error code: %d \n", errno);
}
I am getting this output:
return value: -1
error code: 1
Error code 1 implies an EPERM error. Any ideas as to how should I fix it?

You cannot setuid() to root from a non-root user.
If you want to run your application as root, use Authorization Services, or sudo if it's a command-line tool.

SETUID(2) Man Pages
If the user is not the super user, or the uid specified is not the
real, effective ID, or saved ID,these functions return -1.
setuid(0); will work only from root(SU) user.
error code: 1
#define EPERM 1 /* Operation not permitted */

Related

ssh "packet_write_wait: Connection to x.x.x.x port 22: Broken pipe" -- where is the source code?

We got a client ssh to a remote server showing this error. It has always been running fine, no firewall rules change either. When an ssh session is idled over the weekend, it is still connected. Just some times when we 'less' and shift-F on a file for couple of hours, it shows this error.
I'm not trying to solve this problem in this post. We want to look at the ssh source code to figure out what is going on. On Centos 7, I downloaded openssh-7.4p1-21.el7.src.rpm, and extracted openssh-7.4p1.tar.gz. 'grep' through source code and found 'packet_write_wait' function. But curiously, "Broken pipe" (or -i on each word separately) is not found in all the .h and .c files. Where is that error text coming from?
You can find a copy of the OpenSSH source code in github. The packet_write_wait function is in opacket.c:
void
packet_write_wait(void)
{
int r;
if ((r = ssh_packet_write_wait(active_state)) != 0)
sshpkt_fatal(active_state, __func__, r);
}
It calls another function to write the packet. If that fails, it calls sshpkt_fatal. sshpkt_fatal is in packet.c, and its job is to print an error message and then exit.
/*
* Pretty-print connection-terminating errors and exit.
*/
void
sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
{
switch (r) {
case SSH_ERR_CONN_CLOSED:
logdie("Connection closed by %.200s port %d",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
[...code removed...]
/* FALLTHROUGH */
default:
logdie("%s%sConnection %s %.200s port %d: %s",
tag != NULL ? tag : "", tag != NULL ? ": " : "",
ssh->state->server_side ? "from" : "to",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ssh_err(r));
}
}
The message that you're asking about is handled by the default case. The last argument, which provides the text after the colon, is provided by calling ssh_err:
const char *
ssh_err(int n)
{
switch (n) {
case SSH_ERR_SUCCESS:
return "success";
case SSH_ERR_INTERNAL_ERROR:
return "unexpected internal error";
[...etc...]
The ssh_err case that you're interested in is this one:
case SSH_ERR_SYSTEM_ERROR:
return strerror(errno);
In short, the "Broken pipe" message comes from the standard library function strerror, which converts error numbers to standard error messages.
The list of standard error codes indicates that "Broken pipe" is associated with the EPIPE error.

NetUSerSetInfo does not set UF_PASSWORD_EXPIRED

I'm trying to write an application that is supposed to force a user to change his/her password at next logon. So I have tried to use NetUserSetInfo with structures 1001, 1008, or 1017, on flag UF_PASSWORD_EXPIRED (for 1001 and 1008), and the current epoch (for 1017). I also tried to combine 1008 and 1017. Knowing that I have tested my application from the Administrator account.
I also tried to call NetUserSetInfo with the computer name NULL, "." and "MyComputer" (I found a post saying that it works with). With NULL the return error code is 0. With "." it is ERROR_IO_PENDING, and with"MyComputer"it is "invalid name".
But all the experiments give the same result. I.e. the flag is not set.
I found a post saying that the flag UF_PASSWORD_EXPIRED is for XP only. But it is not compliant with the Windows documentation. And this flag is set if I check "user must change password at next logon" from the control panel.
So how to set this flag programmatically?
Thanks
Unfortunately, the documentation for the Network Management API does not always clearly state whether the state of any particular flag can be changed or is read-only, but I've done some testing, and it looks as if the UF_PASSWORD_EXPIRED flag is one of the read-only ones.
The correct way to force a password reset is using usri4_password_expired,
When you call NetUserAdd or NetUserSetInfo, specify a nonzero value in this member to inform users that they must change their password at the next logon.
This worked for me:
#include <Windows.h>
#include <LM.h>
#pragma comment(lib, "netapi32.lib")
#include <stdio.h>
int wmain(int argc, wchar_t ** argv)
{
// argv[1] must contain the username
DWORD err;
USER_INFO_4 *ui4;
err = NetUserGetInfo(NULL, argv[1], 4, (LPBYTE*)(&ui4));
if (err != 0)
{
printf("NetUserGetInfo: %u\n", err);
return 1;
}
ui4->usri4_password_expired = 1;
err = NetUserSetInfo(NULL, argv[1], 4, (LPBYTE)ui4, NULL);
if (err != 0)
{
printf("NetUserSetInfo: %u\n", err);
return 1;
}
NetApiBufferFree(ui4);
printf("OK\n");
return 0;
}

OSX: shm_open returns ENAMETOOLONG

I am trying atm to create a shared memory file for my process. The filename constists of several parts to identify the process the SHM belongs to and whats its content. An example would be:
shm_pl_dev_system_25077
I create all the files in a directory I created in /tmp where I have full write and read permissions.
So the complete Path would be:
/tmp/pl_dev/shm_pl_dev_system_25077
I create several files there, some fifo pipes and other stuff and also the shm. The only Problem I get is that shm_open will always return the errno 63 (ENAMETOOLONG).
Can you tell me what the issue here is?
Here is the code:
handle_ = ::shm_open(shm_name.get(), O_RDWR, 0755);
if (handle_ == -1 && errno == ENOENT)
{
// SHM does not yet exists, so create it!
handle_ = ::shm_open(shm_name.get(), O_CREAT | O_RDWR, 0755);
if (handle_ != -1) {
created_ = true;
}
else
{
if (!silent_)
{
log.error("Couldn't create the SHM (%d).", errno);
}
return false;
}
}
Okay. As it seems OSX is very limited in the filename of SHMs... The maximum length for a filename currently is 31 chars per section (see PSHMNAMELENGTH in /usr/include/sys/posix_shm.h)

IOBluetoothDevice openConnection fails - identify error code

I am writing a Cocoa application which uses bluetooth. I am trying to connect to a bluetooth device but it fails.
IOBluetoothDevice *btDevice;
// I do search and find the device
btDevice = ;//device found
//btDevice is not nil
IOReturn status = [btDevice openConnection];
if (status != kIOReturnSuccess) {
NSLog( #"Error - failed to connect. %d", status );
}
And I get the device when searches, but openConnection method fails. And NSLog prints
Error = failed to connect. 4
Now what this error code indicates?
I looked at IOKit.framework/IOReturn.h file and it shows many error codes
#define kIOReturnError iokit_common_err(0x2bc) // general error
#define kIOReturnNoMemory iokit_common_err(0x2bd) // can't allocate memory
#define kIOReturnNoResources iokit_common_err(0x2be) // resource shortage
#define kIOReturnIPCError iokit_common_err(0x2bf) // error during IPC
#define kIOReturnNoDevice iokit_common_err(0x2c0) // no such device
.......
//And many more
And I wrote a function to identify what is error code 4
- (void)logError:(OSStatus)status{
if (status == kIOReturnError) {
NSLog(#"kIOReturnError");
}else if(status == kIOReturnNoMemory){
NSLog(#"kIOReturnNoMemory");
}else if(status == kIOReturnNoResources){
NSLog(#"kIOReturnNoResources");
}else if(status == kIOReturnIPCError){
NSLog(#"kIOReturnIPCError");
}else if(status == kIOReturnNoDevice){
......
......
}else{
NSLog(#"No price for you");
}
}
And it prints
No price for you
What does error code 4 imply? Also is there any easier way to identify error reason from OSStatus error codes?
[IOBluetoothDevice openConnection] returns an IOReturn code (which is a I/O Kit specific error number) while your logError: method tests for OSStatus codes.
OSStatus is not the same as IOReturn.
Apple has a Technical Q&A that explains the macros to lookup I/O Kit errors.
http://developer.apple.com/library/mac/#qa/qa1075/_index.html
In your case it seems to be a Mach error (that's probably the 0x4 hi bits of the error that show up as decimal 4 in your log line).
I think the 4 response is actually kBluetoothHCIErrorPageTimeout. The only code I've found that uses this is this: https://www.ida.liu.se/~TDDD63/projects/2013/mindstorms/Installation/Mac/lightblue-0.4-master/src/mac/_bluetoothsockets.py

C - passing an unknown command into execvp()

I'm writing a fake shell, where I create a child process and then call execvp(). In the normal shell, when I enter an unknown command such as 'hello' it returns 'hello: Command not found.' However, when I pass hello into execvp(), it doesn't return any error by default and just continues running the rest of my program like nothing happened. What's the easiest way to find out if nothing was actually run? here's my code:
if(fork() == 0)
{
execvp(cmd, args);
}
else
{
int status = 0;
int corpse = wait(&status);
printf(Child %d exited with a status of %d\n", corpse, status);
}
I know that if corpse < 0, then it's an unknown command, but there are other conditions in my code not listed where I don't want to wait (such as if & is entered at the end of a command). Any suggestions?
All of the exec methods can return -1 if there was an error (errno is set appropriately). You aren't checking the result of execvp so if it fails, the rest of your program will continue executing. You could have something like this to prevent the rest of your program from executing:
if (execvp(cmd, args) == -1)
exit(EXIT_FAILURE);
You also want to check the result of fork() for <0.
You have two independent concerns.
1) is the return value of execvp. It shouldn't return. If it does there is a problem. Here's what I get execvp'ing a bad command. You don't want to wait if execvp fails. Always check the return values.
int res = execvp(argv[1], argv);
printf ("res is %i %s\n", res, strerror(errno));
// => res is -1 No such file or directory
2) The other concern is background processes and such. That's the job of a shell and you're going to need to figure out when your program should wait immediately and when you want to save the pid from fork and wait on it later.

Resources