$NetBSD: patch-ab,v 1.1.1.1 2013/04/10 09:25:22 tonnerre Exp $ Handle OSX-like password APIs. --- shadow.c +++ shadow.c @@ -7,8 +7,16 @@ * License: Free for any use with your own risk! * Modified at: <1999/8/19 06:48:18 by ttate> */ - +#ifndef OSX #include +#define PWTYPE struct spwd +#else +#include +#include +#include +#include +#define PWTYPE struct passwd +#endif #include "ruby.h" #ifdef RUBY19 #include @@ -33,54 +41,84 @@ static VALUE rb_eFileLock; static VALUE rb_shadow_setspent(VALUE self) { + #ifdef OSX + setpassent(1); + #else setspent(); + #endif return Qnil; -}; +} static VALUE rb_shadow_endspent(VALUE self) { + #ifdef OSX + endpwent(); + #else endspent(); + #endif return Qnil; -}; - - +} +#ifdef OSX +static VALUE convert_pw_struct( struct passwd *entry ) +{ + return rb_struct_new(rb_sPasswdEntry, + rb_tainted_str_new2(entry->pw_name), + rb_tainted_str_new2(entry->pw_passwd ), + difftime( entry->pw_change, 0 ) / 24*60*60, + Qnil, /* days that password must stay same */ + Qnil, /* days until passwor changes. */ + Qnil, /* days before expiration where user is warned */ + Qnil, /* days after password expiration that account becomes inactive */ + difftime( entry->pw_expire, 0 ) / 24*60*60, + Qnil, + NULL); +} +#else +static VALUE convert_pw_struct( spwd *entry ) +{ + result = rb_struct_new(rb_sPasswdEntry, + rb_tainted_str_new2(entry->sp_namp), + rb_tainted_str_new2(entry->sp_pwdp), + INT2FIX(entry->sp_lstchg), + INT2FIX(entry->sp_min), + INT2FIX(entry->sp_max), + INT2FIX(entry->sp_warn), + INT2FIX(entry->sp_inact), + INT2FIX(entry->sp_expire), + INT2FIX(entry->sp_flag), + NULL); +} +#endif #ifndef SOLARIS static VALUE rb_shadow_sgetspent(VALUE self, VALUE str) { - struct spwd *entry; + PWTYPE *entry; VALUE result; if( TYPE(str) != T_STRING ) rb_raise(rb_eException,"argument must be a string."); + #ifdef OSX + entry = getpwnam( StringValuePtr(str) ); + #else entry = sgetspent(StringValuePtr(str)); - + #endif if( entry == NULL ) return Qnil; + result = convert_pw_struct( entry ); - result = rb_struct_new(rb_sPasswdEntry, - rb_tainted_str_new2(entry->sp_namp), - rb_tainted_str_new2(entry->sp_pwdp), - INT2FIX(entry->sp_lstchg), - INT2FIX(entry->sp_min), - INT2FIX(entry->sp_max), - INT2FIX(entry->sp_warn), - INT2FIX(entry->sp_inact), - INT2FIX(entry->sp_expire), - INT2FIX(entry->sp_flag), - NULL); free(entry); return result; -}; +} #endif - +#ifndef OSX static VALUE rb_shadow_fgetspent(VALUE self, VALUE file) { - struct spwd *entry; + PWTYPE *entry; VALUE result; if( TYPE(file) != T_FILE ) @@ -91,85 +129,62 @@ rb_shadow_fgetspent(VALUE self, VALUE file) if( entry == NULL ) return Qnil; - result = rb_struct_new(rb_sPasswdEntry, - rb_tainted_str_new2(entry->sp_namp), - rb_tainted_str_new2(entry->sp_pwdp), - INT2FIX(entry->sp_lstchg), - INT2FIX(entry->sp_min), - INT2FIX(entry->sp_max), - INT2FIX(entry->sp_warn), - INT2FIX(entry->sp_inact), - INT2FIX(entry->sp_expire), - INT2FIX(entry->sp_flag), - NULL); + result = convert_pw_struct( entry ); return result; -}; +} +#endif static VALUE rb_shadow_getspent(VALUE self) { - struct spwd *entry; + PWTYPE *entry; VALUE result; - + #ifdef OSX + entry = getpwent(); + #else entry = getspent(); + #endif if( entry == NULL ) return Qnil; - result = rb_struct_new(rb_sPasswdEntry, - rb_tainted_str_new2(entry->sp_namp), - rb_tainted_str_new2(entry->sp_pwdp), - INT2FIX(entry->sp_lstchg), - INT2FIX(entry->sp_min), - INT2FIX(entry->sp_max), - INT2FIX(entry->sp_warn), - INT2FIX(entry->sp_inact), - INT2FIX(entry->sp_expire), - INT2FIX(entry->sp_flag), - NULL); + result = convert_pw_struct( entry ); return result; -}; +} static VALUE rb_shadow_getspnam(VALUE self, VALUE name) { - struct spwd *entry; + PWTYPE *entry; VALUE result; if( TYPE(name) != T_STRING ) rb_raise(rb_eException,"argument must be a string."); - + #ifdef OSX + entry = getpwnam(StringValuePtr(name)); + #else entry = getspnam(StringValuePtr(name)); + #endif if( entry == NULL ) return Qnil; - result = rb_struct_new(rb_sPasswdEntry, - rb_tainted_str_new2(entry->sp_namp), - rb_tainted_str_new2(entry->sp_pwdp), - INT2FIX(entry->sp_lstchg), - INT2FIX(entry->sp_min), - INT2FIX(entry->sp_max), - INT2FIX(entry->sp_warn), - INT2FIX(entry->sp_inact), - INT2FIX(entry->sp_expire), - INT2FIX(entry->sp_flag), - NULL); + result = convert_pw_struct( entry ); return result; -}; - +} +#ifndef OSX static VALUE rb_shadow_putspent(VALUE self, VALUE entry, VALUE file) { - struct spwd centry; + PWTYPE centry; FILE* cfile; VALUE val[9]; int i; int result; for(i=0; i<=8; i++) - val[i] = RSTRUCT_PTR( entry )[i]; //val[i] = RSTRUCT(entry)->ptr[i]; + val[i] = RSTRUCT_PTR( entry )[i]; /* val[i] = RSTRUCT(entry)->ptr[i]; */ cfile = file_ptr( RFILE(file)->fptr ); centry.sp_namp = StringValuePtr(val[0]); @@ -188,7 +203,7 @@ rb_shadow_putspent(VALUE self, VALUE entry, VALUE file) rb_raise(rb_eStandardError,"can't change password"); return Qtrue; -}; +} static VALUE @@ -200,7 +215,7 @@ rb_shadow_lckpwdf(VALUE self) rb_raise(rb_eFileLock,"password file was locked"); else return Qtrue; -}; +} static int in_lock; @@ -225,7 +240,7 @@ rb_shadow_lock(VALUE self) else{ return rb_shadow_lckpwdf(self); }; -}; +} static VALUE @@ -236,13 +251,13 @@ rb_shadow_ulckpwdf(VALUE self) }; ulckpwdf(); return Qtrue; -}; +} static VALUE rb_shadow_unlock(VALUE self) { return rb_shadow_ulckpwdf(self); -}; +} static VALUE rb_shadow_lock_p(VALUE self) @@ -256,8 +271,9 @@ rb_shadow_lock_p(VALUE self) else{ ulckpwdf(); return Qfalse; - }; -}; + } +} +#endif void @@ -283,13 +299,17 @@ Init_shadow() #ifndef SOLARIS rb_define_module_function(rb_mPasswd,"sgetspent",rb_shadow_sgetspent,1); #endif + #ifndef OSX rb_define_module_function(rb_mPasswd,"fgetspent",rb_shadow_fgetspent,1); + #endif rb_define_module_function(rb_mPasswd,"getspent",rb_shadow_getspent,0); rb_define_module_function(rb_mPasswd,"getspnam",rb_shadow_getspnam,1); + #ifndef OSX rb_define_module_function(rb_mPasswd,"putspent",rb_shadow_putspent,2); rb_define_module_function(rb_mPasswd,"lckpwdf",rb_shadow_lckpwdf,0); rb_define_module_function(rb_mPasswd,"lock",rb_shadow_lock,0); rb_define_module_function(rb_mPasswd,"ulckpwdf",rb_shadow_ulckpwdf,0); rb_define_module_function(rb_mPasswd,"unlock",rb_shadow_unlock,0); rb_define_module_function(rb_mPasswd,"lock?",rb_shadow_lock_p,0); -}; + #endif +}